1*5331Samw /* 2*5331Samw * CDDL HEADER START 3*5331Samw * 4*5331Samw * The contents of this file are subject to the terms of the 5*5331Samw * Common Development and Distribution License (the "License"). 6*5331Samw * You may not use this file except in compliance with the License. 7*5331Samw * 8*5331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5331Samw * or http://www.opensolaris.org/os/licensing. 10*5331Samw * See the License for the specific language governing permissions 11*5331Samw * and limitations under the License. 12*5331Samw * 13*5331Samw * When distributing Covered Code, include this CDDL HEADER in each 14*5331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5331Samw * If applicable, add the following below this CDDL HEADER, with the 16*5331Samw * fields enclosed by brackets "[]" replaced with your own identifying 17*5331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 18*5331Samw * 19*5331Samw * CDDL HEADER END 20*5331Samw */ 21*5331Samw /* 22*5331Samw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*5331Samw * Use is subject to license terms. 24*5331Samw */ 25*5331Samw 26*5331Samw #pragma ident "%Z%%M% %I% %E% SMI" 27*5331Samw 28*5331Samw #include <smbsrv/smb_incl.h> 29*5331Samw #include <sys/sdt.h> 30*5331Samw #include <sys/vfs.h> 31*5331Samw #include <sys/vfs_opreg.h> 32*5331Samw #include <sys/vnode.h> 33*5331Samw #include <sys/fem.h> 34*5331Samw 35*5331Samw fem_t *smb_fcn_ops = NULL; 36*5331Samw 37*5331Samw int smb_fem_fcn_create(femarg_t *, char *, vattr_t *, vcexcl_t, int, 38*5331Samw vnode_t **, cred_t *, int, caller_context_t *, vsecattr_t *); 39*5331Samw int smb_fem_fcn_remove(femarg_t *, char *, cred_t *, 40*5331Samw caller_context_t *, int); 41*5331Samw int smb_fem_fcn_rename(femarg_t *, char *, vnode_t *, char *, 42*5331Samw cred_t *, caller_context_t *, int); 43*5331Samw int smb_fem_fcn_mkdir(femarg_t *, char *, vattr_t *, vnode_t **, 44*5331Samw cred_t *, caller_context_t *, int, vsecattr_t *); 45*5331Samw int smb_fem_fcn_rmdir(femarg_t *, char *, vnode_t *, cred_t *, 46*5331Samw caller_context_t *, int); 47*5331Samw int smb_fem_fcn_link(femarg_t *, vnode_t *, char *, cred_t *, 48*5331Samw caller_context_t *, int); 49*5331Samw int smb_fem_fcn_symlink(femarg_t *, char *, vattr_t *, 50*5331Samw char *, cred_t *, caller_context_t *, int); 51*5331Samw 52*5331Samw static const fs_operation_def_t smb_fcn_tmpl[] = { 53*5331Samw VOPNAME_CREATE, { .femop_create = smb_fem_fcn_create }, 54*5331Samw VOPNAME_REMOVE, {.femop_remove = smb_fem_fcn_remove}, 55*5331Samw VOPNAME_RENAME, {.femop_rename = smb_fem_fcn_rename}, 56*5331Samw VOPNAME_MKDIR, {.femop_mkdir = smb_fem_fcn_mkdir}, 57*5331Samw VOPNAME_RMDIR, {.femop_rmdir = smb_fem_fcn_rmdir}, 58*5331Samw VOPNAME_LINK, {.femop_link = smb_fem_fcn_link}, 59*5331Samw VOPNAME_SYMLINK, {.femop_symlink = smb_fem_fcn_symlink}, 60*5331Samw NULL, NULL 61*5331Samw }; 62*5331Samw 63*5331Samw int 64*5331Samw smb_fem_init() 65*5331Samw { 66*5331Samw return (fem_create("smb_fcn_ops", smb_fcn_tmpl, &smb_fcn_ops)); 67*5331Samw } 68*5331Samw 69*5331Samw void 70*5331Samw smb_fem_shutdown() 71*5331Samw { 72*5331Samw if (smb_fcn_ops) 73*5331Samw fem_free(smb_fcn_ops); 74*5331Samw } 75*5331Samw 76*5331Samw void 77*5331Samw smb_fem_fcn_install(smb_node_t *node) 78*5331Samw { 79*5331Samw (void) fem_install(node->vp, smb_fcn_ops, (void *)node, OPARGUNIQ, 80*5331Samw (fem_func_t)smb_node_ref, (fem_func_t)smb_node_release); 81*5331Samw } 82*5331Samw 83*5331Samw void 84*5331Samw smb_fem_fcn_uninstall(smb_node_t *node) 85*5331Samw { 86*5331Samw (void) fem_uninstall(node->vp, smb_fcn_ops, (void *)node); 87*5331Samw } 88*5331Samw 89*5331Samw /* 90*5331Samw * smb_fem_fcn_create() 91*5331Samw * 92*5331Samw * This monitor will catch only changes to VREG files and not to extended 93*5331Samw * attribute files. This is fine because, for CIFS files, stream creates 94*5331Samw * should not trigger any file change notification on the VDIR directory 95*5331Samw * being monitored. Creates of any other kind of extended attribute in 96*5331Samw * the directory will also not trigger any file change notification on the 97*5331Samw * VDIR directory being monitored. 98*5331Samw */ 99*5331Samw 100*5331Samw int 101*5331Samw smb_fem_fcn_create( 102*5331Samw femarg_t *arg, 103*5331Samw char *name, 104*5331Samw vattr_t *vap, 105*5331Samw vcexcl_t excl, 106*5331Samw int mode, 107*5331Samw vnode_t **vpp, 108*5331Samw cred_t *cr, 109*5331Samw int flag, 110*5331Samw caller_context_t *ct, 111*5331Samw vsecattr_t *vsecp) 112*5331Samw { 113*5331Samw smb_node_t *dnode; 114*5331Samw int error; 115*5331Samw 116*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 117*5331Samw 118*5331Samw ASSERT(dnode); 119*5331Samw 120*5331Samw error = vnext_create(arg, name, vap, excl, mode, vpp, cr, flag, 121*5331Samw ct, vsecp); 122*5331Samw 123*5331Samw if (error == 0) 124*5331Samw smb_process_node_notify_change_queue(dnode); 125*5331Samw 126*5331Samw return (error); 127*5331Samw } 128*5331Samw 129*5331Samw /* 130*5331Samw * smb_fem_fcn_remove() 131*5331Samw * 132*5331Samw * This monitor will catch only changes to VREG files and to not extended 133*5331Samw * attribute files. This is fine because, for CIFS files, stream deletes 134*5331Samw * should not trigger any file change notification on the VDIR directory 135*5331Samw * being monitored. Deletes of any other kind of extended attribute in 136*5331Samw * the directory will also not trigger any file change notification on the 137*5331Samw * VDIR directory being monitored. 138*5331Samw */ 139*5331Samw 140*5331Samw int 141*5331Samw smb_fem_fcn_remove( 142*5331Samw femarg_t *arg, 143*5331Samw char *name, 144*5331Samw cred_t *cr, 145*5331Samw caller_context_t *ct, 146*5331Samw int flags) 147*5331Samw { 148*5331Samw smb_node_t *dnode; 149*5331Samw int error; 150*5331Samw 151*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 152*5331Samw 153*5331Samw ASSERT(dnode); 154*5331Samw 155*5331Samw error = vnext_remove(arg, name, cr, ct, flags); 156*5331Samw 157*5331Samw if (error == 0) 158*5331Samw smb_process_node_notify_change_queue(dnode); 159*5331Samw 160*5331Samw return (error); 161*5331Samw } 162*5331Samw 163*5331Samw int 164*5331Samw smb_fem_fcn_rename( 165*5331Samw femarg_t *arg, 166*5331Samw char *snm, 167*5331Samw vnode_t *tdvp, 168*5331Samw char *tnm, 169*5331Samw cred_t *cr, 170*5331Samw caller_context_t *ct, 171*5331Samw int flags) 172*5331Samw { 173*5331Samw smb_node_t *dnode; 174*5331Samw int error; 175*5331Samw 176*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 177*5331Samw 178*5331Samw ASSERT(dnode); 179*5331Samw 180*5331Samw error = vnext_rename(arg, snm, tdvp, tnm, cr, ct, flags); 181*5331Samw 182*5331Samw if (error == 0) 183*5331Samw smb_process_node_notify_change_queue(dnode); 184*5331Samw 185*5331Samw return (error); 186*5331Samw } 187*5331Samw 188*5331Samw int 189*5331Samw smb_fem_fcn_mkdir( 190*5331Samw femarg_t *arg, 191*5331Samw char *name, 192*5331Samw vattr_t *vap, 193*5331Samw vnode_t **vpp, 194*5331Samw cred_t *cr, 195*5331Samw caller_context_t *ct, 196*5331Samw int flags, 197*5331Samw vsecattr_t *vsecp) 198*5331Samw { 199*5331Samw smb_node_t *dnode; 200*5331Samw int error; 201*5331Samw 202*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 203*5331Samw 204*5331Samw ASSERT(dnode); 205*5331Samw 206*5331Samw error = vnext_mkdir(arg, name, vap, vpp, cr, ct, flags, vsecp); 207*5331Samw 208*5331Samw if (error == 0) 209*5331Samw smb_process_node_notify_change_queue(dnode); 210*5331Samw 211*5331Samw return (error); 212*5331Samw } 213*5331Samw 214*5331Samw int 215*5331Samw smb_fem_fcn_rmdir( 216*5331Samw femarg_t *arg, 217*5331Samw char *name, 218*5331Samw vnode_t *cdir, 219*5331Samw cred_t *cr, 220*5331Samw caller_context_t *ct, 221*5331Samw int flags) 222*5331Samw { 223*5331Samw smb_node_t *dnode; 224*5331Samw int error; 225*5331Samw 226*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 227*5331Samw 228*5331Samw ASSERT(dnode); 229*5331Samw 230*5331Samw error = vnext_rmdir(arg, name, cdir, cr, ct, flags); 231*5331Samw 232*5331Samw if (error == 0) 233*5331Samw smb_process_node_notify_change_queue(dnode); 234*5331Samw 235*5331Samw return (error); 236*5331Samw } 237*5331Samw 238*5331Samw int 239*5331Samw smb_fem_fcn_link( 240*5331Samw femarg_t *arg, 241*5331Samw vnode_t *svp, 242*5331Samw char *tnm, 243*5331Samw cred_t *cr, 244*5331Samw caller_context_t *ct, 245*5331Samw int flags) 246*5331Samw { 247*5331Samw smb_node_t *dnode; 248*5331Samw int error; 249*5331Samw 250*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 251*5331Samw 252*5331Samw ASSERT(dnode); 253*5331Samw 254*5331Samw error = vnext_link(arg, svp, tnm, cr, ct, flags); 255*5331Samw 256*5331Samw if (error == 0) 257*5331Samw smb_process_node_notify_change_queue(dnode); 258*5331Samw 259*5331Samw return (error); 260*5331Samw } 261*5331Samw 262*5331Samw int 263*5331Samw smb_fem_fcn_symlink( 264*5331Samw femarg_t *arg, 265*5331Samw char *linkname, 266*5331Samw vattr_t *vap, 267*5331Samw char *target, 268*5331Samw cred_t *cr, 269*5331Samw caller_context_t *ct, 270*5331Samw int flags) 271*5331Samw { 272*5331Samw smb_node_t *dnode; 273*5331Samw int error; 274*5331Samw 275*5331Samw dnode = (smb_node_t *)arg->fa_fnode->fn_available; 276*5331Samw 277*5331Samw ASSERT(dnode); 278*5331Samw 279*5331Samw error = vnext_symlink(arg, linkname, vap, target, cr, ct, flags); 280*5331Samw 281*5331Samw if (error == 0) 282*5331Samw smb_process_node_notify_change_queue(dnode); 283*5331Samw 284*5331Samw return (error); 285*5331Samw } 286