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 * 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 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 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 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 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 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 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 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 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 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 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