1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 3898 rsb * Common Development and Distribution License (the "License"). 6 3898 rsb * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 6073 acruz * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #include <sys/types.h> 27 0 stevel #include <sys/param.h> 28 0 stevel #include <sys/time.h> 29 0 stevel #include <sys/cred.h> 30 0 stevel #include <sys/vfs.h> 31 3898 rsb #include <sys/vfs_opreg.h> 32 0 stevel #include <sys/gfs.h> 33 0 stevel #include <sys/vnode.h> 34 0 stevel #include <sys/systm.h> 35 0 stevel #include <sys/errno.h> 36 0 stevel #include <sys/sysmacros.h> 37 0 stevel #include <fs/fs_subr.h> 38 0 stevel #include <sys/contract.h> 39 0 stevel #include <sys/contract_impl.h> 40 0 stevel #include <sys/ctfs.h> 41 0 stevel #include <sys/ctfs_impl.h> 42 0 stevel #include <sys/file.h> 43 6073 acruz #include <sys/model.h> 44 0 stevel 45 0 stevel /* 46 0 stevel * CTFS routines for the /system/contract/<type>/template vnode. 47 0 stevel */ 48 0 stevel 49 0 stevel /* 50 0 stevel * ctfs_create_tmplnode 51 0 stevel * 52 0 stevel * Creates a new template and tdirnode, and returns the tdirnode. 53 0 stevel */ 54 0 stevel vnode_t * 55 0 stevel ctfs_create_tmplnode(vnode_t *pvp) 56 0 stevel { 57 0 stevel vnode_t *vp; 58 0 stevel ctfs_tmplnode_t *tmplnode; 59 0 stevel 60 0 stevel ASSERT(gfs_file_index(pvp) < ct_ntypes); 61 0 stevel 62 0 stevel vp = gfs_file_create(sizeof (ctfs_tmplnode_t), pvp, ctfs_ops_tmpl); 63 0 stevel tmplnode = vp->v_data; 64 0 stevel tmplnode->ctfs_tmn_tmpl = 65 0 stevel ct_types[gfs_file_index(pvp)]->ct_type_default(); 66 0 stevel 67 0 stevel return (vp); 68 0 stevel } 69 0 stevel 70 0 stevel /* 71 0 stevel * ctfs_tmpl_open - VOP_OPEN entry point 72 0 stevel * 73 0 stevel * Just ensures the right mode bits are set. 74 0 stevel */ 75 0 stevel /* ARGSUSED */ 76 0 stevel static int 77 5331 amw ctfs_tmpl_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct) 78 0 stevel { 79 0 stevel if (flag != (FREAD | FWRITE | FOFFMAX)) 80 0 stevel return (EINVAL); 81 0 stevel 82 0 stevel return (0); 83 0 stevel } 84 0 stevel 85 0 stevel /* 86 0 stevel * ctfs_tmpl_getattr - VOP_GETATTR entry point 87 0 stevel */ 88 0 stevel /* ARGSUSED */ 89 0 stevel static int 90 5331 amw ctfs_tmpl_getattr( 91 5331 amw vnode_t *vp, 92 5331 amw vattr_t *vap, 93 5331 amw int flags, 94 5331 amw cred_t *cr, 95 5331 amw caller_context_t *ct) 96 0 stevel { 97 0 stevel vap->va_type = VREG; 98 0 stevel vap->va_mode = 0666; 99 0 stevel vap->va_nlink = 1; 100 0 stevel vap->va_size = 0; 101 0 stevel vap->va_ctime.tv_sec = vp->v_vfsp->vfs_mtime; 102 0 stevel vap->va_ctime.tv_nsec = 0; 103 0 stevel vap->va_atime = vap->va_mtime = vap->va_ctime; 104 0 stevel ctfs_common_getattr(vp, vap); 105 0 stevel 106 0 stevel return (0); 107 0 stevel } 108 0 stevel 109 0 stevel /* 110 0 stevel * ctfs_tmpl_ioctl - VOP_IOCTL entry point 111 0 stevel * 112 0 stevel * All the ct_tmpl_*(3contract) interfaces point here. 113 0 stevel */ 114 0 stevel /* ARGSUSED */ 115 0 stevel static int 116 5331 amw ctfs_tmpl_ioctl( 117 5331 amw vnode_t *vp, 118 5331 amw int cmd, 119 5331 amw intptr_t arg, 120 5331 amw int flag, 121 5331 amw cred_t *cr, 122 5331 amw int *rvalp, 123 5331 amw caller_context_t *ct) 124 0 stevel { 125 0 stevel ctfs_tmplnode_t *tmplnode = vp->v_data; 126 7937 Antonello ct_kparam_t kparam; 127 7937 Antonello ct_param_t *param = &kparam.param; 128 4845 vikram ctid_t ctid; 129 0 stevel int error; 130 0 stevel 131 0 stevel switch (cmd) { 132 0 stevel case CT_TACTIVATE: 133 0 stevel ASSERT(tmplnode->ctfs_tmn_tmpl != NULL); 134 0 stevel ctmpl_activate(tmplnode->ctfs_tmn_tmpl); 135 0 stevel break; 136 0 stevel case CT_TCLEAR: 137 0 stevel ASSERT(tmplnode->ctfs_tmn_tmpl != NULL); 138 0 stevel ctmpl_clear(tmplnode->ctfs_tmn_tmpl); 139 0 stevel break; 140 0 stevel case CT_TCREATE: 141 0 stevel ASSERT(tmplnode->ctfs_tmn_tmpl != NULL); 142 4845 vikram error = ctmpl_create(tmplnode->ctfs_tmn_tmpl, &ctid); 143 4845 vikram if (error) 144 4845 vikram return (error); 145 4845 vikram *rvalp = ctid; 146 4845 vikram break; 147 0 stevel case CT_TSET: 148 7937 Antonello error = ctparam_copyin((void *)arg, &kparam, flag, cmd); 149 7937 Antonello if (error != 0) 150 7937 Antonello return (error); 151 7937 Antonello error = ctmpl_set(tmplnode->ctfs_tmn_tmpl, &kparam, cr); 152 7937 Antonello kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 153 7937 Antonello 154 6073 acruz return (error); 155 0 stevel case CT_TGET: 156 7937 Antonello error = ctparam_copyin((void *)arg, &kparam, flag, cmd); 157 7937 Antonello if (error != 0) 158 7937 Antonello return (error); 159 7937 Antonello error = ctmpl_get(tmplnode->ctfs_tmn_tmpl, &kparam); 160 7937 Antonello if (error != 0) { 161 7937 Antonello kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 162 7937 Antonello } else { 163 7937 Antonello error = ctparam_copyout(&kparam, (void *)arg, flag); 164 7937 Antonello } 165 7937 Antonello 166 6073 acruz return (error); 167 0 stevel default: 168 0 stevel return (EINVAL); 169 0 stevel } 170 0 stevel 171 0 stevel return (0); 172 0 stevel } 173 0 stevel 174 0 stevel /* 175 0 stevel * ctfs_tmpl_inactive - VOP_INACTIVE entry point 176 0 stevel */ 177 0 stevel /* ARGSUSED */ 178 0 stevel static void 179 5331 amw ctfs_tmpl_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 180 0 stevel { 181 0 stevel ctfs_tmplnode_t *tmplnode; 182 0 stevel 183 0 stevel if ((tmplnode = gfs_file_inactive(vp)) != NULL) { 184 0 stevel ctmpl_free(tmplnode->ctfs_tmn_tmpl); 185 0 stevel kmem_free(tmplnode, sizeof (ctfs_tmplnode_t)); 186 0 stevel } 187 0 stevel } 188 0 stevel 189 0 stevel const fs_operation_def_t ctfs_tops_tmpl[] = { 190 3898 rsb { VOPNAME_OPEN, { .vop_open = ctfs_tmpl_open } }, 191 3898 rsb { VOPNAME_CLOSE, { .vop_close = ctfs_close } }, 192 3898 rsb { VOPNAME_IOCTL, { .vop_ioctl = ctfs_tmpl_ioctl } }, 193 3898 rsb { VOPNAME_GETATTR, { .vop_getattr = ctfs_tmpl_getattr } }, 194 3898 rsb { VOPNAME_ACCESS, { .vop_access = ctfs_access_readwrite } }, 195 3898 rsb { VOPNAME_READDIR, { .error = fs_notdir } }, 196 3898 rsb { VOPNAME_LOOKUP, { .error = fs_notdir } }, 197 3898 rsb { VOPNAME_INACTIVE, { .vop_inactive = ctfs_tmpl_inactive } }, 198 0 stevel { NULL, NULL } 199 0 stevel }; 200