1aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2aecfc01dSrui zang - Sun Microsystems - Beijing China * CDDL HEADER START
3aecfc01dSrui zang - Sun Microsystems - Beijing China *
4aecfc01dSrui zang - Sun Microsystems - Beijing China * The contents of this file are subject to the terms of the
5aecfc01dSrui zang - Sun Microsystems - Beijing China * Common Development and Distribution License (the "License").
6aecfc01dSrui zang - Sun Microsystems - Beijing China * You may not use this file except in compliance with the License.
7aecfc01dSrui zang - Sun Microsystems - Beijing China *
8aecfc01dSrui zang - Sun Microsystems - Beijing China * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9aecfc01dSrui zang - Sun Microsystems - Beijing China * or http://www.opensolaris.org/os/licensing.
10aecfc01dSrui zang - Sun Microsystems - Beijing China * See the License for the specific language governing permissions
11aecfc01dSrui zang - Sun Microsystems - Beijing China * and limitations under the License.
12aecfc01dSrui zang - Sun Microsystems - Beijing China *
13aecfc01dSrui zang - Sun Microsystems - Beijing China * When distributing Covered Code, include this CDDL HEADER in each
14aecfc01dSrui zang - Sun Microsystems - Beijing China * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15aecfc01dSrui zang - Sun Microsystems - Beijing China * If applicable, add the following below this CDDL HEADER, with the
16aecfc01dSrui zang - Sun Microsystems - Beijing China * fields enclosed by brackets "[]" replaced with your own identifying
17aecfc01dSrui zang - Sun Microsystems - Beijing China * information: Portions Copyright [yyyy] [name of copyright owner]
18aecfc01dSrui zang - Sun Microsystems - Beijing China *
19aecfc01dSrui zang - Sun Microsystems - Beijing China * CDDL HEADER END
20aecfc01dSrui zang - Sun Microsystems - Beijing China */
21aecfc01dSrui zang - Sun Microsystems - Beijing China /*
22ceeba6f9Srui zang - Sun Microsystems - Beijing China * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23aecfc01dSrui zang - Sun Microsystems - Beijing China */
24aecfc01dSrui zang - Sun Microsystems - Beijing China
25aecfc01dSrui zang - Sun Microsystems - Beijing China /*
26aecfc01dSrui zang - Sun Microsystems - Beijing China * vnode ops for the /dev/vt directory
27aecfc01dSrui zang - Sun Microsystems - Beijing China */
28aecfc01dSrui zang - Sun Microsystems - Beijing China
29aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/types.h>
30aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/param.h>
31aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sysmacros.h>
32aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sunndi.h>
33aecfc01dSrui zang - Sun Microsystems - Beijing China #include <fs/fs_subr.h>
34aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/fs/dv_node.h>
35aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/fs/sdev_impl.h>
36aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/policy.h>
37aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/stat.h>
38aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/vfs_opreg.h>
39aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/tty.h>
40aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/vt_impl.h>
41aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/note.h>
42aecfc01dSrui zang - Sun Microsystems - Beijing China
43aecfc01dSrui zang - Sun Microsystems - Beijing China /* warlock in this file only cares about variables shared by vt and devfs */
44aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(SCHEME_PROTECTS_DATA("Do not care", sdev_node vattr vnode))
45aecfc01dSrui zang - Sun Microsystems - Beijing China
46aecfc01dSrui zang - Sun Microsystems - Beijing China #define DEVVT_UID_DEFAULT SDEV_UID_DEFAULT
47aecfc01dSrui zang - Sun Microsystems - Beijing China #define DEVVT_GID_DEFAULT (0)
48aecfc01dSrui zang - Sun Microsystems - Beijing China #define DEVVT_DEVMODE_DEFAULT (0600)
49aecfc01dSrui zang - Sun Microsystems - Beijing China #define DEVVT_ACTIVE_NAME "active"
50ceeba6f9Srui zang - Sun Microsystems - Beijing China #define DEVVT_CONSUSER_NAME "console_user"
51aecfc01dSrui zang - Sun Microsystems - Beijing China
52aecfc01dSrui zang - Sun Microsystems - Beijing China #define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
53aecfc01dSrui zang - Sun Microsystems - Beijing China
54aecfc01dSrui zang - Sun Microsystems - Beijing China /* attributes for VT nodes */
55aecfc01dSrui zang - Sun Microsystems - Beijing China static vattr_t devvt_vattr = {
56aecfc01dSrui zang - Sun Microsystems - Beijing China AT_TYPE|AT_MODE|AT_UID|AT_GID, /* va_mask */
57aecfc01dSrui zang - Sun Microsystems - Beijing China VCHR, /* va_type */
58aecfc01dSrui zang - Sun Microsystems - Beijing China S_IFCHR | DEVVT_DEVMODE_DEFAULT, /* va_mode */
59aecfc01dSrui zang - Sun Microsystems - Beijing China DEVVT_UID_DEFAULT, /* va_uid */
60aecfc01dSrui zang - Sun Microsystems - Beijing China DEVVT_GID_DEFAULT, /* va_gid */
61aecfc01dSrui zang - Sun Microsystems - Beijing China 0 /* 0 hereafter */
62aecfc01dSrui zang - Sun Microsystems - Beijing China };
63aecfc01dSrui zang - Sun Microsystems - Beijing China
64aecfc01dSrui zang - Sun Microsystems - Beijing China struct vnodeops *devvt_vnodeops;
65aecfc01dSrui zang - Sun Microsystems - Beijing China
66aecfc01dSrui zang - Sun Microsystems - Beijing China struct vnodeops *
devvt_getvnodeops(void)67aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_getvnodeops(void)
68aecfc01dSrui zang - Sun Microsystems - Beijing China {
69aecfc01dSrui zang - Sun Microsystems - Beijing China return (devvt_vnodeops);
70aecfc01dSrui zang - Sun Microsystems - Beijing China }
71aecfc01dSrui zang - Sun Microsystems - Beijing China
72aecfc01dSrui zang - Sun Microsystems - Beijing China static int
devvt_str2minor(const char * nm,minor_t * mp)73aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_str2minor(const char *nm, minor_t *mp)
74aecfc01dSrui zang - Sun Microsystems - Beijing China {
75aecfc01dSrui zang - Sun Microsystems - Beijing China long uminor = 0;
76aecfc01dSrui zang - Sun Microsystems - Beijing China char *endptr = NULL;
77aecfc01dSrui zang - Sun Microsystems - Beijing China
78aecfc01dSrui zang - Sun Microsystems - Beijing China if (nm == NULL || !isdigit(*nm))
79aecfc01dSrui zang - Sun Microsystems - Beijing China return (EINVAL);
80aecfc01dSrui zang - Sun Microsystems - Beijing China
81aecfc01dSrui zang - Sun Microsystems - Beijing China *mp = 0;
82aecfc01dSrui zang - Sun Microsystems - Beijing China if (ddi_strtol(nm, &endptr, 10, &uminor) != 0 ||
83aecfc01dSrui zang - Sun Microsystems - Beijing China *endptr != '\0' || uminor < 0) {
84aecfc01dSrui zang - Sun Microsystems - Beijing China return (EINVAL);
85aecfc01dSrui zang - Sun Microsystems - Beijing China }
86aecfc01dSrui zang - Sun Microsystems - Beijing China
87aecfc01dSrui zang - Sun Microsystems - Beijing China *mp = (minor_t)uminor;
88aecfc01dSrui zang - Sun Microsystems - Beijing China return (0);
89aecfc01dSrui zang - Sun Microsystems - Beijing China }
90aecfc01dSrui zang - Sun Microsystems - Beijing China
912b080a34SJerry Gilliam /*
922b080a34SJerry Gilliam * Validate that a node is up-to-date and correct.
932b080a34SJerry Gilliam * A validator may not update the node state or
942b080a34SJerry Gilliam * contents as a read lock permits entry by
952b080a34SJerry Gilliam * multiple threads.
962b080a34SJerry Gilliam */
97aecfc01dSrui zang - Sun Microsystems - Beijing China int
devvt_validate(struct sdev_node * dv)98aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_validate(struct sdev_node *dv)
99aecfc01dSrui zang - Sun Microsystems - Beijing China {
100aecfc01dSrui zang - Sun Microsystems - Beijing China minor_t min;
101aecfc01dSrui zang - Sun Microsystems - Beijing China char *nm = dv->sdev_name;
1022b080a34SJerry Gilliam int rval;
103aecfc01dSrui zang - Sun Microsystems - Beijing China
104aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(dv->sdev_state == SDEV_READY);
1052b080a34SJerry Gilliam ASSERT(RW_LOCK_HELD(&(dv->sdev_dotdot)->sdev_contents));
106aecfc01dSrui zang - Sun Microsystems - Beijing China
107aecfc01dSrui zang - Sun Microsystems - Beijing China /* validate only READY nodes */
108aecfc01dSrui zang - Sun Microsystems - Beijing China if (dv->sdev_state != SDEV_READY) {
109aecfc01dSrui zang - Sun Microsystems - Beijing China sdcmn_err(("dev fs: skipping: node not ready %s(%p)",
110aecfc01dSrui zang - Sun Microsystems - Beijing China nm, (void *)dv));
111aecfc01dSrui zang - Sun Microsystems - Beijing China return (SDEV_VTOR_SKIP);
112aecfc01dSrui zang - Sun Microsystems - Beijing China }
113aecfc01dSrui zang - Sun Microsystems - Beijing China
114aecfc01dSrui zang - Sun Microsystems - Beijing China if (vt_wc_attached() == (major_t)-1)
115aecfc01dSrui zang - Sun Microsystems - Beijing China return (SDEV_VTOR_INVALID);
116aecfc01dSrui zang - Sun Microsystems - Beijing China
117aecfc01dSrui zang - Sun Microsystems - Beijing China if (strcmp(nm, DEVVT_ACTIVE_NAME) == 0) {
118aecfc01dSrui zang - Sun Microsystems - Beijing China char *link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
119aecfc01dSrui zang - Sun Microsystems - Beijing China (void) vt_getactive(link, MAXPATHLEN);
1202b080a34SJerry Gilliam rval = (strcmp(link, dv->sdev_symlink) == 0) ?
1212b080a34SJerry Gilliam SDEV_VTOR_VALID : SDEV_VTOR_STALE;
122aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(link, MAXPATHLEN);
1232b080a34SJerry Gilliam return (rval);
124ceeba6f9Srui zang - Sun Microsystems - Beijing China }
125ceeba6f9Srui zang - Sun Microsystems - Beijing China
126ceeba6f9Srui zang - Sun Microsystems - Beijing China if (strcmp(nm, DEVVT_CONSUSER_NAME) == 0) {
127ceeba6f9Srui zang - Sun Microsystems - Beijing China char *link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
128ceeba6f9Srui zang - Sun Microsystems - Beijing China (void) vt_getconsuser(link, MAXPATHLEN);
1292b080a34SJerry Gilliam rval = (strcmp(link, dv->sdev_symlink) == 0) ?
1302b080a34SJerry Gilliam SDEV_VTOR_VALID : SDEV_VTOR_STALE;
131ceeba6f9Srui zang - Sun Microsystems - Beijing China kmem_free(link, MAXPATHLEN);
1322b080a34SJerry Gilliam return (rval);
133ceeba6f9Srui zang - Sun Microsystems - Beijing China }
134ceeba6f9Srui zang - Sun Microsystems - Beijing China
135ceeba6f9Srui zang - Sun Microsystems - Beijing China if (devvt_str2minor(nm, &min) != 0) {
136aecfc01dSrui zang - Sun Microsystems - Beijing China return (SDEV_VTOR_INVALID);
137aecfc01dSrui zang - Sun Microsystems - Beijing China }
138aecfc01dSrui zang - Sun Microsystems - Beijing China
139aecfc01dSrui zang - Sun Microsystems - Beijing China if (vt_minor_valid(min) == B_FALSE)
140aecfc01dSrui zang - Sun Microsystems - Beijing China return (SDEV_VTOR_INVALID);
141aecfc01dSrui zang - Sun Microsystems - Beijing China
142aecfc01dSrui zang - Sun Microsystems - Beijing China return (SDEV_VTOR_VALID);
143aecfc01dSrui zang - Sun Microsystems - Beijing China }
144aecfc01dSrui zang - Sun Microsystems - Beijing China
145aecfc01dSrui zang - Sun Microsystems - Beijing China /*
146aecfc01dSrui zang - Sun Microsystems - Beijing China * This callback is invoked from devname_lookup_func() to create
147aecfc01dSrui zang - Sun Microsystems - Beijing China * a entry when the node is not found in the cache.
148aecfc01dSrui zang - Sun Microsystems - Beijing China */
149aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
150aecfc01dSrui zang - Sun Microsystems - Beijing China static int
devvt_create_rvp(struct sdev_node * ddv,char * nm,void ** arg,cred_t * cred,void * whatever,char * whichever)151aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create_rvp(struct sdev_node *ddv, char *nm,
152aecfc01dSrui zang - Sun Microsystems - Beijing China void **arg, cred_t *cred, void *whatever, char *whichever)
153aecfc01dSrui zang - Sun Microsystems - Beijing China {
154aecfc01dSrui zang - Sun Microsystems - Beijing China minor_t min;
155aecfc01dSrui zang - Sun Microsystems - Beijing China major_t maj;
156aecfc01dSrui zang - Sun Microsystems - Beijing China struct vattr *vap = (struct vattr *)arg;
157aecfc01dSrui zang - Sun Microsystems - Beijing China
158aecfc01dSrui zang - Sun Microsystems - Beijing China if ((maj = vt_wc_attached()) == (major_t)-1)
159aecfc01dSrui zang - Sun Microsystems - Beijing China return (SDEV_VTOR_INVALID);
160aecfc01dSrui zang - Sun Microsystems - Beijing China
161aecfc01dSrui zang - Sun Microsystems - Beijing China if (strcmp(nm, DEVVT_ACTIVE_NAME) == 0) {
162aecfc01dSrui zang - Sun Microsystems - Beijing China (void) vt_getactive((char *)*arg, MAXPATHLEN);
163aecfc01dSrui zang - Sun Microsystems - Beijing China return (0);
164aecfc01dSrui zang - Sun Microsystems - Beijing China }
165aecfc01dSrui zang - Sun Microsystems - Beijing China
166ceeba6f9Srui zang - Sun Microsystems - Beijing China if (strcmp(nm, DEVVT_CONSUSER_NAME) == 0) {
167ceeba6f9Srui zang - Sun Microsystems - Beijing China (void) vt_getconsuser((char *)*arg, MAXPATHLEN);
168ceeba6f9Srui zang - Sun Microsystems - Beijing China return (0);
169ceeba6f9Srui zang - Sun Microsystems - Beijing China }
170aecfc01dSrui zang - Sun Microsystems - Beijing China if (devvt_str2minor(nm, &min) != 0)
171aecfc01dSrui zang - Sun Microsystems - Beijing China return (-1);
172aecfc01dSrui zang - Sun Microsystems - Beijing China
173aecfc01dSrui zang - Sun Microsystems - Beijing China if (vt_minor_valid(min) == B_FALSE)
174aecfc01dSrui zang - Sun Microsystems - Beijing China return (-1);
175aecfc01dSrui zang - Sun Microsystems - Beijing China
176aecfc01dSrui zang - Sun Microsystems - Beijing China *vap = devvt_vattr;
177aecfc01dSrui zang - Sun Microsystems - Beijing China vap->va_rdev = makedevice(maj, min);
178aecfc01dSrui zang - Sun Microsystems - Beijing China
179aecfc01dSrui zang - Sun Microsystems - Beijing China return (0);
180aecfc01dSrui zang - Sun Microsystems - Beijing China }
181aecfc01dSrui zang - Sun Microsystems - Beijing China
182aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED3*/
183aecfc01dSrui zang - Sun Microsystems - Beijing China static int
devvt_lookup(struct vnode * dvp,char * nm,struct vnode ** vpp,struct pathname * pnp,int flags,struct vnode * rdir,struct cred * cred,caller_context_t * ct,int * direntflags,pathname_t * realpnp)184aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_lookup(struct vnode *dvp, char *nm, struct vnode **vpp,
185aecfc01dSrui zang - Sun Microsystems - Beijing China struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cred,
186aecfc01dSrui zang - Sun Microsystems - Beijing China caller_context_t *ct, int *direntflags, pathname_t *realpnp)
187aecfc01dSrui zang - Sun Microsystems - Beijing China {
188aecfc01dSrui zang - Sun Microsystems - Beijing China struct sdev_node *sdvp = VTOSDEV(dvp);
189aecfc01dSrui zang - Sun Microsystems - Beijing China struct sdev_node *dv;
190aecfc01dSrui zang - Sun Microsystems - Beijing China struct vnode *rvp = NULL;
191aecfc01dSrui zang - Sun Microsystems - Beijing China int type, error;
192aecfc01dSrui zang - Sun Microsystems - Beijing China
193ceeba6f9Srui zang - Sun Microsystems - Beijing China if ((strcmp(nm, DEVVT_ACTIVE_NAME) == 0) ||
194ceeba6f9Srui zang - Sun Microsystems - Beijing China (strcmp(nm, DEVVT_CONSUSER_NAME) == 0)) {
195aecfc01dSrui zang - Sun Microsystems - Beijing China type = SDEV_VLINK;
196aecfc01dSrui zang - Sun Microsystems - Beijing China } else {
197aecfc01dSrui zang - Sun Microsystems - Beijing China type = SDEV_VATTR;
198aecfc01dSrui zang - Sun Microsystems - Beijing China }
199aecfc01dSrui zang - Sun Microsystems - Beijing China
200aecfc01dSrui zang - Sun Microsystems - Beijing China /* Give warlock a more clear call graph */
201aecfc01dSrui zang - Sun Microsystems - Beijing China #ifndef __lock_lint
202aecfc01dSrui zang - Sun Microsystems - Beijing China error = devname_lookup_func(sdvp, nm, vpp, cred,
203aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create_rvp, type);
204aecfc01dSrui zang - Sun Microsystems - Beijing China #else
205aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create_rvp(0, 0, 0, 0, 0, 0);
206aecfc01dSrui zang - Sun Microsystems - Beijing China #endif
207aecfc01dSrui zang - Sun Microsystems - Beijing China
208aecfc01dSrui zang - Sun Microsystems - Beijing China if (error == 0) {
209aecfc01dSrui zang - Sun Microsystems - Beijing China switch ((*vpp)->v_type) {
210aecfc01dSrui zang - Sun Microsystems - Beijing China case VCHR:
211aecfc01dSrui zang - Sun Microsystems - Beijing China dv = VTOSDEV(VTOS(*vpp)->s_realvp);
212aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(VOP_REALVP(SDEVTOV(dv), &rvp, NULL) == ENOSYS);
213aecfc01dSrui zang - Sun Microsystems - Beijing China break;
214aecfc01dSrui zang - Sun Microsystems - Beijing China case VDIR:
215aecfc01dSrui zang - Sun Microsystems - Beijing China case VLNK:
216aecfc01dSrui zang - Sun Microsystems - Beijing China dv = VTOSDEV(*vpp);
217aecfc01dSrui zang - Sun Microsystems - Beijing China break;
218aecfc01dSrui zang - Sun Microsystems - Beijing China default:
219aecfc01dSrui zang - Sun Microsystems - Beijing China cmn_err(CE_PANIC, "devvt_lookup: Unsupported node "
220aecfc01dSrui zang - Sun Microsystems - Beijing China "type: %p: %d", (void *)(*vpp), (*vpp)->v_type);
221aecfc01dSrui zang - Sun Microsystems - Beijing China break;
222aecfc01dSrui zang - Sun Microsystems - Beijing China }
223aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(SDEV_HELD(dv));
224aecfc01dSrui zang - Sun Microsystems - Beijing China }
225aecfc01dSrui zang - Sun Microsystems - Beijing China
226aecfc01dSrui zang - Sun Microsystems - Beijing China return (error);
227aecfc01dSrui zang - Sun Microsystems - Beijing China }
228aecfc01dSrui zang - Sun Microsystems - Beijing China
229aecfc01dSrui zang - Sun Microsystems - Beijing China static void
devvt_create_snode(struct sdev_node * ddv,char * nm,struct cred * cred,int type)230aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create_snode(struct sdev_node *ddv, char *nm, struct cred *cred, int type)
231aecfc01dSrui zang - Sun Microsystems - Beijing China {
232aecfc01dSrui zang - Sun Microsystems - Beijing China int error;
233aecfc01dSrui zang - Sun Microsystems - Beijing China struct sdev_node *sdv = NULL;
234bb5fffbeSJerry Gilliam struct vattr vattr;
235bb5fffbeSJerry Gilliam struct vattr *vap = &vattr;
236aecfc01dSrui zang - Sun Microsystems - Beijing China major_t maj;
237aecfc01dSrui zang - Sun Microsystems - Beijing China minor_t min;
238aecfc01dSrui zang - Sun Microsystems - Beijing China
2392b080a34SJerry Gilliam ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
2402b080a34SJerry Gilliam
241aecfc01dSrui zang - Sun Microsystems - Beijing China if ((maj = vt_wc_attached()) == (major_t)-1)
242aecfc01dSrui zang - Sun Microsystems - Beijing China return;
243aecfc01dSrui zang - Sun Microsystems - Beijing China
244aecfc01dSrui zang - Sun Microsystems - Beijing China if (strcmp(nm, DEVVT_ACTIVE_NAME) != 0 &&
245ceeba6f9Srui zang - Sun Microsystems - Beijing China strcmp(nm, DEVVT_CONSUSER_NAME) != 0 &&
246aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_str2minor(nm, &min) != 0)
247aecfc01dSrui zang - Sun Microsystems - Beijing China return;
248aecfc01dSrui zang - Sun Microsystems - Beijing China
249aecfc01dSrui zang - Sun Microsystems - Beijing China error = sdev_mknode(ddv, nm, &sdv, NULL, NULL, NULL, cred, SDEV_INIT);
250aecfc01dSrui zang - Sun Microsystems - Beijing China if (error || !sdv) {
251aecfc01dSrui zang - Sun Microsystems - Beijing China return;
252aecfc01dSrui zang - Sun Microsystems - Beijing China }
253aecfc01dSrui zang - Sun Microsystems - Beijing China
254aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&sdv->sdev_lookup_lock);
255aecfc01dSrui zang - Sun Microsystems - Beijing China SDEV_BLOCK_OTHERS(sdv, SDEV_LOOKUP);
256aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&sdv->sdev_lookup_lock);
257aecfc01dSrui zang - Sun Microsystems - Beijing China
258aecfc01dSrui zang - Sun Microsystems - Beijing China if (type & SDEV_VATTR) {
259bb5fffbeSJerry Gilliam *vap = devvt_vattr;
260aecfc01dSrui zang - Sun Microsystems - Beijing China vap->va_rdev = makedevice(maj, min);
261aecfc01dSrui zang - Sun Microsystems - Beijing China error = sdev_mknode(ddv, nm, &sdv, vap, NULL,
262aecfc01dSrui zang - Sun Microsystems - Beijing China NULL, cred, SDEV_READY);
263aecfc01dSrui zang - Sun Microsystems - Beijing China } else if (type & SDEV_VLINK) {
264aecfc01dSrui zang - Sun Microsystems - Beijing China char *link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
265aecfc01dSrui zang - Sun Microsystems - Beijing China
266aecfc01dSrui zang - Sun Microsystems - Beijing China (void) vt_getactive(link, MAXPATHLEN);
267bb5fffbeSJerry Gilliam *vap = sdev_vattr_lnk;
268aecfc01dSrui zang - Sun Microsystems - Beijing China vap->va_size = strlen(link);
269aecfc01dSrui zang - Sun Microsystems - Beijing China error = sdev_mknode(ddv, nm, &sdv, vap, NULL,
270aecfc01dSrui zang - Sun Microsystems - Beijing China (void *)link, cred, SDEV_READY);
271aecfc01dSrui zang - Sun Microsystems - Beijing China
272aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(link, MAXPATHLEN);
273aecfc01dSrui zang - Sun Microsystems - Beijing China }
274aecfc01dSrui zang - Sun Microsystems - Beijing China
275*9e5aa9d8SRobert Mustacchi if (error != 0) {
276*9e5aa9d8SRobert Mustacchi SDEV_RELE(sdv);
277*9e5aa9d8SRobert Mustacchi return;
278*9e5aa9d8SRobert Mustacchi }
279*9e5aa9d8SRobert Mustacchi
280aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&sdv->sdev_lookup_lock);
281aecfc01dSrui zang - Sun Microsystems - Beijing China SDEV_UNBLOCK_OTHERS(sdv, SDEV_LOOKUP);
282aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&sdv->sdev_lookup_lock);
283aecfc01dSrui zang - Sun Microsystems - Beijing China
284aecfc01dSrui zang - Sun Microsystems - Beijing China }
285aecfc01dSrui zang - Sun Microsystems - Beijing China
286aecfc01dSrui zang - Sun Microsystems - Beijing China static void
devvt_rebuild_stale_link(struct sdev_node * ddv,struct sdev_node * dv)2872b080a34SJerry Gilliam devvt_rebuild_stale_link(struct sdev_node *ddv, struct sdev_node *dv)
2882b080a34SJerry Gilliam {
2892b080a34SJerry Gilliam char *link;
2902b080a34SJerry Gilliam
2912b080a34SJerry Gilliam ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
2922b080a34SJerry Gilliam
2932b080a34SJerry Gilliam ASSERT((strcmp(dv->sdev_name, DEVVT_ACTIVE_NAME) == 0) ||
2942b080a34SJerry Gilliam (strcmp(dv->sdev_name, DEVVT_CONSUSER_NAME) == 0));
2952b080a34SJerry Gilliam
2962b080a34SJerry Gilliam link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
2972b080a34SJerry Gilliam if (strcmp(dv->sdev_name, DEVVT_ACTIVE_NAME) == 0) {
2982b080a34SJerry Gilliam (void) vt_getactive(link, MAXPATHLEN);
2992b080a34SJerry Gilliam } else if (strcmp(dv->sdev_name, DEVVT_CONSUSER_NAME) == 0) {
3002b080a34SJerry Gilliam (void) vt_getconsuser(link, MAXPATHLEN);
3012b080a34SJerry Gilliam }
3022b080a34SJerry Gilliam
3032b080a34SJerry Gilliam if (strcmp(link, dv->sdev_symlink) != 0) {
3042b080a34SJerry Gilliam strfree(dv->sdev_symlink);
3052b080a34SJerry Gilliam dv->sdev_symlink = strdup(link);
3062b080a34SJerry Gilliam dv->sdev_attr->va_size = strlen(link);
3072b080a34SJerry Gilliam }
3082b080a34SJerry Gilliam kmem_free(link, MAXPATHLEN);
3092b080a34SJerry Gilliam }
3102b080a34SJerry Gilliam
3112b080a34SJerry Gilliam /*
3122b080a34SJerry Gilliam * First step in refreshing directory contents.
3132b080a34SJerry Gilliam * Remove each invalid entry and rebuild the link
3142b080a34SJerry Gilliam * reference for each stale entry.
3152b080a34SJerry Gilliam */
3162b080a34SJerry Gilliam static void
devvt_prunedir(struct sdev_node * ddv)317aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_prunedir(struct sdev_node *ddv)
318aecfc01dSrui zang - Sun Microsystems - Beijing China {
319aecfc01dSrui zang - Sun Microsystems - Beijing China struct vnode *vp;
320aecfc01dSrui zang - Sun Microsystems - Beijing China struct sdev_node *dv, *next = NULL;
321aecfc01dSrui zang - Sun Microsystems - Beijing China int (*vtor)(struct sdev_node *) = NULL;
322aecfc01dSrui zang - Sun Microsystems - Beijing China
323aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(ddv->sdev_flags & SDEV_VTOR);
324aecfc01dSrui zang - Sun Microsystems - Beijing China
325aecfc01dSrui zang - Sun Microsystems - Beijing China vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
326aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(vtor);
327aecfc01dSrui zang - Sun Microsystems - Beijing China
328aecfc01dSrui zang - Sun Microsystems - Beijing China for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) {
329aecfc01dSrui zang - Sun Microsystems - Beijing China next = SDEV_NEXT_ENTRY(ddv, dv);
330aecfc01dSrui zang - Sun Microsystems - Beijing China
331aecfc01dSrui zang - Sun Microsystems - Beijing China switch (vtor(dv)) {
332aecfc01dSrui zang - Sun Microsystems - Beijing China case SDEV_VTOR_VALID:
3332b080a34SJerry Gilliam break;
334aecfc01dSrui zang - Sun Microsystems - Beijing China case SDEV_VTOR_SKIP:
3352b080a34SJerry Gilliam break;
336aecfc01dSrui zang - Sun Microsystems - Beijing China case SDEV_VTOR_INVALID:
3372b080a34SJerry Gilliam vp = SDEVTOV(dv);
3382b080a34SJerry Gilliam if (vp->v_count != 0)
3392b080a34SJerry Gilliam break;
3402b080a34SJerry Gilliam /* remove the cached node */
3412b080a34SJerry Gilliam SDEV_HOLD(dv);
3422b080a34SJerry Gilliam (void) sdev_cache_update(ddv, &dv,
3432b080a34SJerry Gilliam dv->sdev_name, SDEV_CACHE_DELETE);
344*9e5aa9d8SRobert Mustacchi SDEV_RELE(dv);
3452b080a34SJerry Gilliam break;
346b127ac41SPhilip Kirk case SDEV_VTOR_STALE:
3472b080a34SJerry Gilliam devvt_rebuild_stale_link(ddv, dv);
348aecfc01dSrui zang - Sun Microsystems - Beijing China break;
349aecfc01dSrui zang - Sun Microsystems - Beijing China }
350aecfc01dSrui zang - Sun Microsystems - Beijing China }
351aecfc01dSrui zang - Sun Microsystems - Beijing China }
352aecfc01dSrui zang - Sun Microsystems - Beijing China
353aecfc01dSrui zang - Sun Microsystems - Beijing China static void
devvt_cleandir(struct vnode * dvp,struct cred * cred)354aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_cleandir(struct vnode *dvp, struct cred *cred)
355aecfc01dSrui zang - Sun Microsystems - Beijing China {
356aecfc01dSrui zang - Sun Microsystems - Beijing China struct sdev_node *sdvp = VTOSDEV(dvp);
357aecfc01dSrui zang - Sun Microsystems - Beijing China struct sdev_node *dv, *next = NULL;
358aecfc01dSrui zang - Sun Microsystems - Beijing China int min, cnt;
359ceeba6f9Srui zang - Sun Microsystems - Beijing China char found = 0;
360aecfc01dSrui zang - Sun Microsystems - Beijing China
361aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&vc_lock);
362aecfc01dSrui zang - Sun Microsystems - Beijing China cnt = VC_INSTANCES_COUNT;
363aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&vc_lock);
364aecfc01dSrui zang - Sun Microsystems - Beijing China
365aecfc01dSrui zang - Sun Microsystems - Beijing China /* We have to fool warlock this way, otherwise it will complain */
366aecfc01dSrui zang - Sun Microsystems - Beijing China #ifndef __lock_lint
367aecfc01dSrui zang - Sun Microsystems - Beijing China if (rw_tryupgrade(&sdvp->sdev_contents) == NULL) {
368aecfc01dSrui zang - Sun Microsystems - Beijing China rw_exit(&sdvp->sdev_contents);
369aecfc01dSrui zang - Sun Microsystems - Beijing China rw_enter(&sdvp->sdev_contents, RW_WRITER);
370aecfc01dSrui zang - Sun Microsystems - Beijing China }
371aecfc01dSrui zang - Sun Microsystems - Beijing China #else
372aecfc01dSrui zang - Sun Microsystems - Beijing China rw_enter(&sdvp->sdev_contents, RW_WRITER);
373aecfc01dSrui zang - Sun Microsystems - Beijing China #endif
374aecfc01dSrui zang - Sun Microsystems - Beijing China
3752b080a34SJerry Gilliam /* 1. prune invalid nodes and rebuild stale symlinks */
3762b080a34SJerry Gilliam devvt_prunedir(sdvp);
3772b080a34SJerry Gilliam
3782b080a34SJerry Gilliam /* 2. create missing nodes */
379aecfc01dSrui zang - Sun Microsystems - Beijing China for (min = 0; min < cnt; min++) {
380aecfc01dSrui zang - Sun Microsystems - Beijing China char nm[16];
381aecfc01dSrui zang - Sun Microsystems - Beijing China
382aecfc01dSrui zang - Sun Microsystems - Beijing China if (vt_minor_valid(min) == B_FALSE)
383aecfc01dSrui zang - Sun Microsystems - Beijing China continue;
384aecfc01dSrui zang - Sun Microsystems - Beijing China
385aecfc01dSrui zang - Sun Microsystems - Beijing China (void) snprintf(nm, sizeof (nm), "%d", min);
386aecfc01dSrui zang - Sun Microsystems - Beijing China found = 0;
387aecfc01dSrui zang - Sun Microsystems - Beijing China for (dv = SDEV_FIRST_ENTRY(sdvp); dv; dv = next) {
388aecfc01dSrui zang - Sun Microsystems - Beijing China next = SDEV_NEXT_ENTRY(sdvp, dv);
389aecfc01dSrui zang - Sun Microsystems - Beijing China
3902b080a34SJerry Gilliam /* validate only ready nodes */
391aecfc01dSrui zang - Sun Microsystems - Beijing China if (dv->sdev_state != SDEV_READY)
392aecfc01dSrui zang - Sun Microsystems - Beijing China continue;
393aecfc01dSrui zang - Sun Microsystems - Beijing China if (strcmp(nm, dv->sdev_name) == 0) {
394aecfc01dSrui zang - Sun Microsystems - Beijing China found = 1;
395aecfc01dSrui zang - Sun Microsystems - Beijing China break;
396aecfc01dSrui zang - Sun Microsystems - Beijing China }
397aecfc01dSrui zang - Sun Microsystems - Beijing China }
398aecfc01dSrui zang - Sun Microsystems - Beijing China if (!found) {
399aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create_snode(sdvp, nm, cred, SDEV_VATTR);
400aecfc01dSrui zang - Sun Microsystems - Beijing China }
401aecfc01dSrui zang - Sun Microsystems - Beijing China }
402aecfc01dSrui zang - Sun Microsystems - Beijing China
4032b080a34SJerry Gilliam /* 3. create active link node and console user link node */
404aecfc01dSrui zang - Sun Microsystems - Beijing China found = 0;
405aecfc01dSrui zang - Sun Microsystems - Beijing China for (dv = SDEV_FIRST_ENTRY(sdvp); dv; dv = next) {
406aecfc01dSrui zang - Sun Microsystems - Beijing China next = SDEV_NEXT_ENTRY(sdvp, dv);
407aecfc01dSrui zang - Sun Microsystems - Beijing China
4082b080a34SJerry Gilliam /* validate only ready nodes */
409aecfc01dSrui zang - Sun Microsystems - Beijing China if (dv->sdev_state != SDEV_READY)
410aecfc01dSrui zang - Sun Microsystems - Beijing China continue;
411ceeba6f9Srui zang - Sun Microsystems - Beijing China if ((strcmp(dv->sdev_name, DEVVT_ACTIVE_NAME) == NULL))
412ceeba6f9Srui zang - Sun Microsystems - Beijing China found |= 0x01;
413ceeba6f9Srui zang - Sun Microsystems - Beijing China if ((strcmp(dv->sdev_name, DEVVT_CONSUSER_NAME) == NULL))
414ceeba6f9Srui zang - Sun Microsystems - Beijing China found |= 0x02;
415ceeba6f9Srui zang - Sun Microsystems - Beijing China
416ceeba6f9Srui zang - Sun Microsystems - Beijing China if ((found & 0x01) && (found & 0x02))
417aecfc01dSrui zang - Sun Microsystems - Beijing China break;
418aecfc01dSrui zang - Sun Microsystems - Beijing China }
419ceeba6f9Srui zang - Sun Microsystems - Beijing China if (!(found & 0x01))
420aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create_snode(sdvp, DEVVT_ACTIVE_NAME, cred, SDEV_VLINK);
421ceeba6f9Srui zang - Sun Microsystems - Beijing China if (!(found & 0x02))
422ceeba6f9Srui zang - Sun Microsystems - Beijing China devvt_create_snode(sdvp, DEVVT_CONSUSER_NAME, cred, SDEV_VLINK);
423ceeba6f9Srui zang - Sun Microsystems - Beijing China
424aecfc01dSrui zang - Sun Microsystems - Beijing China #ifndef __lock_lint
425aecfc01dSrui zang - Sun Microsystems - Beijing China rw_downgrade(&sdvp->sdev_contents);
426aecfc01dSrui zang - Sun Microsystems - Beijing China #else
427aecfc01dSrui zang - Sun Microsystems - Beijing China rw_exit(&sdvp->sdev_contents);
428aecfc01dSrui zang - Sun Microsystems - Beijing China #endif
429aecfc01dSrui zang - Sun Microsystems - Beijing China }
430aecfc01dSrui zang - Sun Microsystems - Beijing China
431aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED4*/
432aecfc01dSrui zang - Sun Microsystems - Beijing China static int
devvt_readdir(struct vnode * dvp,struct uio * uiop,struct cred * cred,int * eofp,caller_context_t * ct,int flags)433aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_readdir(struct vnode *dvp, struct uio *uiop, struct cred *cred,
434aecfc01dSrui zang - Sun Microsystems - Beijing China int *eofp, caller_context_t *ct, int flags)
435aecfc01dSrui zang - Sun Microsystems - Beijing China {
436aecfc01dSrui zang - Sun Microsystems - Beijing China if (uiop->uio_offset == 0) {
437aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_cleandir(dvp, cred);
438aecfc01dSrui zang - Sun Microsystems - Beijing China }
439aecfc01dSrui zang - Sun Microsystems - Beijing China
440aecfc01dSrui zang - Sun Microsystems - Beijing China return (devname_readdir_func(dvp, uiop, cred, eofp, 0));
441aecfc01dSrui zang - Sun Microsystems - Beijing China }
442aecfc01dSrui zang - Sun Microsystems - Beijing China
443aecfc01dSrui zang - Sun Microsystems - Beijing China /*
444aecfc01dSrui zang - Sun Microsystems - Beijing China * We allow create to find existing nodes
445aecfc01dSrui zang - Sun Microsystems - Beijing China * - if the node doesn't exist - EROFS
446aecfc01dSrui zang - Sun Microsystems - Beijing China * - creating an existing dir read-only succeeds, otherwise EISDIR
447aecfc01dSrui zang - Sun Microsystems - Beijing China * - exclusive creates fail - EEXIST
448aecfc01dSrui zang - Sun Microsystems - Beijing China */
449aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED2*/
450aecfc01dSrui zang - Sun Microsystems - Beijing China static int
devvt_create(struct vnode * dvp,char * nm,struct vattr * vap,vcexcl_t excl,int mode,struct vnode ** vpp,struct cred * cred,int flag,caller_context_t * ct,vsecattr_t * vsecp)451aecfc01dSrui zang - Sun Microsystems - Beijing China devvt_create(struct vnode *dvp, char *nm, struct vattr *vap, vcexcl_t excl,
452aecfc01dSrui zang - Sun Microsystems - Beijing China int mode, struct vnode **vpp, struct cred *cred, int flag,
453aecfc01dSrui zang - Sun Microsystems - Beijing China caller_context_t *ct, vsecattr_t *vsecp)
454aecfc01dSrui zang - Sun Microsystems - Beijing China {
455aecfc01dSrui zang - Sun Microsystems - Beijing China int error;
456aecfc01dSrui zang - Sun Microsystems - Beijing China struct vnode *vp;
457aecfc01dSrui zang - Sun Microsystems - Beijing China
458aecfc01dSrui zang - Sun Microsystems - Beijing China *vpp = NULL;
459aecfc01dSrui zang - Sun Microsystems - Beijing China
460aecfc01dSrui zang - Sun Microsystems - Beijing China if ((error = devvt_lookup(dvp, nm, &vp, NULL, 0, NULL, cred, ct, NULL,
461aecfc01dSrui zang - Sun Microsystems - Beijing China NULL)) != 0) {
462aecfc01dSrui zang - Sun Microsystems - Beijing China if (error == ENOENT)
463aecfc01dSrui zang - Sun Microsystems - Beijing China error = EROFS;
464aecfc01dSrui zang - Sun Microsystems - Beijing China return (error);
465aecfc01dSrui zang - Sun Microsystems - Beijing China }
466aecfc01dSrui zang - Sun Microsystems - Beijing China
467aecfc01dSrui zang - Sun Microsystems - Beijing China if (excl == EXCL)
468aecfc01dSrui zang - Sun Microsystems - Beijing China error = EEXIST;
469aecfc01dSrui zang - Sun Microsystems - Beijing China else if (vp->v_type == VDIR && (mode & VWRITE))
470aecfc01dSrui zang - Sun Microsystems - Beijing China error = EISDIR;
471aecfc01dSrui zang - Sun Microsystems - Beijing China else
472aecfc01dSrui zang - Sun Microsystems - Beijing China error = VOP_ACCESS(vp, mode, 0, cred, ct);
473aecfc01dSrui zang - Sun Microsystems - Beijing China
474aecfc01dSrui zang - Sun Microsystems - Beijing China if (error) {
475aecfc01dSrui zang - Sun Microsystems - Beijing China VN_RELE(vp);
476aecfc01dSrui zang - Sun Microsystems - Beijing China } else
477aecfc01dSrui zang - Sun Microsystems - Beijing China *vpp = vp;
478aecfc01dSrui zang - Sun Microsystems - Beijing China
479aecfc01dSrui zang - Sun Microsystems - Beijing China return (error);
480aecfc01dSrui zang - Sun Microsystems - Beijing China }
481aecfc01dSrui zang - Sun Microsystems - Beijing China
482aecfc01dSrui zang - Sun Microsystems - Beijing China const fs_operation_def_t devvt_vnodeops_tbl[] = {
483aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_READDIR, { .vop_readdir = devvt_readdir },
484aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_LOOKUP, { .vop_lookup = devvt_lookup },
485aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_CREATE, { .vop_create = devvt_create },
486aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_REMOVE, { .error = fs_nosys },
487aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_MKDIR, { .error = fs_nosys },
488aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_RMDIR, { .error = fs_nosys },
489aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_SYMLINK, { .error = fs_nosys },
490aecfc01dSrui zang - Sun Microsystems - Beijing China VOPNAME_SETSECATTR, { .error = fs_nosys },
491aecfc01dSrui zang - Sun Microsystems - Beijing China NULL, NULL
492aecfc01dSrui zang - Sun Microsystems - Beijing China };
493