1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * SMB Node State Machine 27 * ---------------------- 28 * 29 * 30 * +----------- Creation/Allocation 31 * | 32 * | T0 33 * | 34 * v 35 * +----------------------------+ T1 36 * | SMB_NODE_STATE_AVAILABLE |--------------------+ 37 * +----------------------------+ | 38 * | ^ | 39 * | | v 40 * | | T2 +-------------------------------+ 41 * | |<---------| SMB_NODE_STATE_OPLOCK_GRANTED | 42 * | | +-------------------------------+ 43 * | T5 | | 44 * | | | T3 45 * | | v 46 * | | T4 +--------------------------------+ 47 * | +----------| SMB_NODE_STATE_OPLOCK_BREAKING | 48 * | +--------------------------------+ 49 * | 50 * v 51 * +-----------------------------+ 52 * | SMB_NODE_STATE_DESTROYING | 53 * +-----------------------------+ 54 * | 55 * | 56 * | T6 57 * | 58 * +----------> Deletion/Free 59 * 60 * Transition T0 61 * 62 * This transition occurs in smb_node_lookup(). If the node looked for is 63 * not found in the has table a new node is created. The reference count is 64 * initialized to 1 and the state initialized to SMB_NODE_STATE_AVAILABLE. 65 * 66 * Transition T1 67 * 68 * This transition occurs smb_oplock_acquire() during an OPEN. 69 * 70 * Transition T2 71 * 72 * This transition occurs in smb_oplock_release(). The events triggering 73 * it are: 74 * 75 * - LockingAndX sent by the client that was granted the oplock. 76 * - Closing of the file. 77 * 78 * Transition T3 79 * 80 * This transition occurs in smb_oplock_break(). The events triggering 81 * it are: 82 * 83 * - Another client wants to open the file. 84 * - A client is trying to delete the file. 85 * - A client is trying to rename the file. 86 * - A client is trying to set/modify the file attributes. 87 * 88 * Transition T4 89 * 90 * This transition occurs in smb_oplock_release or smb_oplock_break(). The 91 * events triggering it are: 92 * 93 * - The client that was granting the oplock releases it (close or 94 * LockingAndx). 95 * - The time alloted to release the oplock expired. 96 * 97 * Transition T5 98 * 99 * This transition occurs in smb_node_release(). If the reference count 100 * drops to zero the state is moved to SMB_NODE_STATE_DESTROYING and no more 101 * reference count will be given out for that node. 102 * 103 * Transition T6 104 * 105 * This transition occurs in smb_node_release(). The structure is deleted. 106 * 107 * Comments 108 * -------- 109 * 110 * The reason the smb node has 2 states is the following synchronization 111 * rule: 112 * 113 * There's a mutex embedded in the node used to protect its fields and 114 * there's a lock embedded in the bucket of the hash table the node belongs 115 * to. To increment or to decrement the reference count the mutex must be 116 * entered. To insert the node into the bucket and to remove it from the 117 * bucket the lock must be entered in RW_WRITER mode. When both (mutex and 118 * lock) have to be entered, the lock has always to be entered first then 119 * the mutex. This prevents a deadlock between smb_node_lookup() and 120 * smb_node_release() from occurring. However, in smb_node_release() when the 121 * reference count drops to zero and triggers the deletion of the node, the 122 * mutex has to be released before entering the lock of the bucket (to 123 * remove the node). This creates a window during which the node that is 124 * about to be freed could be given out by smb_node_lookup(). To close that 125 * window the node is moved to the state SMB_NODE_STATE_DESTROYING before 126 * releasing the mutex. That way, even if smb_node_lookup() finds it, the 127 * state will indicate that the node should be treated as non existent (of 128 * course the state of the node should be tested/updated under the 129 * protection of the mutex). 130 */ 131 #include <smbsrv/smb_incl.h> 132 #include <smbsrv/smb_fsops.h> 133 #include <smbsrv/smb_kstat.h> 134 #include <sys/pathname.h> 135 #include <sys/sdt.h> 136 #include <sys/nbmlock.h> 137 138 uint32_t smb_is_executable(char *); 139 static void smb_node_delete_on_close(smb_node_t *); 140 static void smb_node_create_audit_buf(smb_node_t *, int); 141 static void smb_node_destroy_audit_buf(smb_node_t *); 142 static void smb_node_audit(smb_node_t *); 143 static smb_node_t *smb_node_alloc(char *, vnode_t *, smb_llist_t *, uint32_t); 144 static void smb_node_free(smb_node_t *); 145 static int smb_node_constructor(void *, void *, int); 146 static void smb_node_destructor(void *, void *); 147 static smb_llist_t *smb_node_get_hash(fsid_t *, smb_attr_t *, uint32_t *); 148 static void smb_node_init_cached_timestamps(smb_node_t *); 149 static void smb_node_clear_cached_timestamps(smb_node_t *); 150 static void smb_node_get_cached_timestamps(smb_node_t *, smb_attr_t *); 151 static void smb_node_set_cached_timestamps(smb_node_t *, smb_attr_t *); 152 153 #define VALIDATE_DIR_NODE(_dir_, _node_) \ 154 ASSERT((_dir_)->n_magic == SMB_NODE_MAGIC); \ 155 ASSERT(((_dir_)->vp->v_xattrdir) || ((_dir_)->vp->v_type == VDIR)); \ 156 ASSERT((_dir_)->dir_snode != (_node_)); 157 158 static kmem_cache_t *smb_node_cache = NULL; 159 static boolean_t smb_node_initialized = B_FALSE; 160 static smb_llist_t smb_node_hash_table[SMBND_HASH_MASK+1]; 161 162 /* 163 * smb_node_init 164 * 165 * Initialization of the SMB node layer. 166 * 167 * This function is not multi-thread safe. The caller must make sure only one 168 * thread makes the call. 169 */ 170 int 171 smb_node_init(void) 172 { 173 int i; 174 175 if (smb_node_initialized) 176 return (0); 177 smb_node_cache = kmem_cache_create(SMBSRV_KSTAT_NODE_CACHE, 178 sizeof (smb_node_t), 8, smb_node_constructor, smb_node_destructor, 179 NULL, NULL, NULL, 0); 180 181 for (i = 0; i <= SMBND_HASH_MASK; i++) { 182 smb_llist_constructor(&smb_node_hash_table[i], 183 sizeof (smb_node_t), offsetof(smb_node_t, n_lnd)); 184 } 185 smb_node_initialized = B_TRUE; 186 return (0); 187 } 188 189 /* 190 * smb_node_fini 191 * 192 * This function is not multi-thread safe. The caller must make sure only one 193 * thread makes the call. 194 */ 195 void 196 smb_node_fini(void) 197 { 198 int i; 199 200 if (!smb_node_initialized) 201 return; 202 203 #ifdef DEBUG 204 for (i = 0; i <= SMBND_HASH_MASK; i++) { 205 smb_node_t *node; 206 207 /* 208 * The following sequence is just intended for sanity check. 209 * This will have to be modified when the code goes into 210 * production. 211 * 212 * The SMB node hash table should be emtpy at this point. If the 213 * hash table is not empty a panic will be triggered. 214 * 215 * The reason why SMB nodes are still remaining in the hash 216 * table is problably due to a mismatch between calls to 217 * smb_node_lookup() and smb_node_release(). You must track that 218 * down. 219 */ 220 node = smb_llist_head(&smb_node_hash_table[i]); 221 ASSERT(node == NULL); 222 } 223 #endif 224 225 for (i = 0; i <= SMBND_HASH_MASK; i++) { 226 smb_llist_destructor(&smb_node_hash_table[i]); 227 } 228 kmem_cache_destroy(smb_node_cache); 229 smb_node_cache = NULL; 230 smb_node_initialized = B_FALSE; 231 } 232 233 /* 234 * smb_node_lookup() 235 * 236 * NOTE: This routine should only be called by the file system interface layer, 237 * and not by SMB. 238 * 239 * smb_node_lookup() is called upon successful lookup, mkdir, and create 240 * (for both non-streams and streams). In each of these cases, a held vnode is 241 * passed into this routine. If a new smb_node is created it will take its 242 * own hold on the vnode. The caller's hold therefore still belongs to, and 243 * should be released by, the caller. 244 * 245 * A reference is taken on the smb_node whether found in the hash table 246 * or newly created. 247 * 248 * If an smb_node needs to be created, a reference is also taken on the 249 * dir_snode (if passed in). 250 * 251 * See smb_node_release() for details on the release of these references. 252 */ 253 254 /*ARGSUSED*/ 255 smb_node_t * 256 smb_node_lookup( 257 struct smb_request *sr, 258 struct open_param *op, 259 cred_t *cred, 260 vnode_t *vp, 261 char *od_name, 262 smb_node_t *dir_snode, 263 smb_node_t *unnamed_node) 264 { 265 smb_llist_t *node_hdr; 266 smb_node_t *node; 267 smb_attr_t attr; 268 uint32_t hashkey = 0; 269 fsid_t fsid; 270 int error; 271 krw_t lock_mode; 272 vnode_t *unnamed_vp = NULL; 273 274 /* 275 * smb_vop_getattr() is called here instead of smb_fsop_getattr(), 276 * because the node may not yet exist. We also do not want to call 277 * it with the list lock held. 278 */ 279 280 if (unnamed_node) 281 unnamed_vp = unnamed_node->vp; 282 283 /* 284 * This getattr is performed on behalf of the server 285 * that's why kcred is used not the user's cred 286 */ 287 attr.sa_mask = SMB_AT_ALL; 288 error = smb_vop_getattr(vp, unnamed_vp, &attr, 0, kcred); 289 if (error) 290 return (NULL); 291 292 if (sr && sr->tid_tree) { 293 /* 294 * The fsid for a file is that of the tree, even 295 * if the file resides in a different mountpoint 296 * under the share. 297 */ 298 fsid = SMB_TREE_FSID(sr->tid_tree); 299 } else { 300 /* 301 * This should be getting executed only for the 302 * tree root smb_node. 303 */ 304 fsid = vp->v_vfsp->vfs_fsid; 305 } 306 307 node_hdr = smb_node_get_hash(&fsid, &attr, &hashkey); 308 lock_mode = RW_READER; 309 310 smb_llist_enter(node_hdr, lock_mode); 311 for (;;) { 312 node = list_head(&node_hdr->ll_list); 313 while (node) { 314 ASSERT(node->n_magic == SMB_NODE_MAGIC); 315 ASSERT(node->n_hash_bucket == node_hdr); 316 if ((node->n_hashkey == hashkey) && (node->vp == vp)) { 317 mutex_enter(&node->n_mutex); 318 DTRACE_PROBE1(smb_node_lookup_hit, 319 smb_node_t *, node); 320 switch (node->n_state) { 321 case SMB_NODE_STATE_OPLOCK_GRANTED: 322 case SMB_NODE_STATE_OPLOCK_BREAKING: 323 case SMB_NODE_STATE_AVAILABLE: 324 /* The node was found. */ 325 node->n_refcnt++; 326 if ((node->dir_snode == NULL) && 327 (dir_snode != NULL) && 328 (strcmp(od_name, "..") != 0) && 329 (strcmp(od_name, ".") != 0)) { 330 VALIDATE_DIR_NODE(dir_snode, 331 node); 332 node->dir_snode = dir_snode; 333 smb_node_ref(dir_snode); 334 } 335 336 smb_node_audit(node); 337 mutex_exit(&node->n_mutex); 338 smb_llist_exit(node_hdr); 339 return (node); 340 341 case SMB_NODE_STATE_DESTROYING: 342 /* 343 * Although the node exists it is about 344 * to be destroyed. We act as it hasn't 345 * been found. 346 */ 347 mutex_exit(&node->n_mutex); 348 break; 349 default: 350 /* 351 * Although the node exists it is in an 352 * unknown state. We act as it hasn't 353 * been found. 354 */ 355 ASSERT(0); 356 mutex_exit(&node->n_mutex); 357 break; 358 } 359 } 360 node = smb_llist_next(node_hdr, node); 361 } 362 if ((lock_mode == RW_READER) && smb_llist_upgrade(node_hdr)) { 363 lock_mode = RW_WRITER; 364 continue; 365 } 366 break; 367 } 368 node = smb_node_alloc(od_name, vp, node_hdr, hashkey); 369 node->n_orig_uid = crgetuid(sr->user_cr); 370 371 if (op) 372 node->flags |= smb_is_executable(op->fqi.fq_last_comp); 373 374 if (dir_snode) { 375 smb_node_ref(dir_snode); 376 node->dir_snode = dir_snode; 377 ASSERT(dir_snode->dir_snode != node); 378 ASSERT((dir_snode->vp->v_xattrdir) || 379 (dir_snode->vp->v_type == VDIR)); 380 } 381 382 if (unnamed_node) { 383 smb_node_ref(unnamed_node); 384 node->unnamed_stream_node = unnamed_node; 385 } 386 387 DTRACE_PROBE1(smb_node_lookup_miss, smb_node_t *, node); 388 smb_node_audit(node); 389 smb_llist_insert_head(node_hdr, node); 390 smb_llist_exit(node_hdr); 391 return (node); 392 } 393 394 /* 395 * smb_stream_node_lookup() 396 * 397 * Note: stream_name (the name that will be stored in the "od_name" field 398 * of a stream's smb_node) is the same as the on-disk name for the stream 399 * except that it does not have SMB_STREAM_PREFIX prepended. 400 */ 401 402 smb_node_t * 403 smb_stream_node_lookup(smb_request_t *sr, cred_t *cr, smb_node_t *fnode, 404 vnode_t *xattrdirvp, vnode_t *vp, char *stream_name) 405 { 406 smb_node_t *xattrdir_node; 407 smb_node_t *snode; 408 409 xattrdir_node = smb_node_lookup(sr, NULL, cr, xattrdirvp, XATTR_DIR, 410 fnode, NULL); 411 412 if (xattrdir_node == NULL) 413 return (NULL); 414 415 snode = smb_node_lookup(sr, NULL, cr, vp, stream_name, xattrdir_node, 416 fnode); 417 418 (void) smb_node_release(xattrdir_node); 419 return (snode); 420 } 421 422 423 /* 424 * This function should be called whenever a reference is needed on an 425 * smb_node pointer. The copy of an smb_node pointer from one non-local 426 * data structure to another requires a reference to be taken on the smb_node 427 * (unless the usage is localized). Each data structure deallocation routine 428 * will call smb_node_release() on its smb_node pointers. 429 * 430 * In general, an smb_node pointer residing in a structure should never be 431 * stale. A node pointer may be NULL, however, and care should be taken 432 * prior to calling smb_node_ref(), which ASSERTs that the pointer is valid. 433 * Care also needs to be taken with respect to racing deallocations of a 434 * structure. 435 */ 436 void 437 smb_node_ref(smb_node_t *node) 438 { 439 SMB_NODE_VALID(node); 440 441 mutex_enter(&node->n_mutex); 442 switch (node->n_state) { 443 case SMB_NODE_STATE_AVAILABLE: 444 case SMB_NODE_STATE_OPLOCK_GRANTED: 445 case SMB_NODE_STATE_OPLOCK_BREAKING: 446 node->n_refcnt++; 447 ASSERT(node->n_refcnt); 448 DTRACE_PROBE1(smb_node_ref_exit, smb_node_t *, node); 449 smb_node_audit(node); 450 break; 451 default: 452 SMB_PANIC(); 453 } 454 mutex_exit(&node->n_mutex); 455 } 456 457 /* 458 * smb_node_lookup() takes a hold on an smb_node, whether found in the 459 * hash table or newly created. This hold is expected to be released 460 * in the following manner. 461 * 462 * smb_node_lookup() takes an address of an smb_node pointer. This should 463 * be getting passed down via a lookup (whether path name or component), mkdir, 464 * create. If the original smb_node pointer resides in a data structure, then 465 * the deallocation routine for the data structure is responsible for calling 466 * smb_node_release() on the smb_node pointer. Alternatively, 467 * smb_node_release() can be called as soon as the smb_node pointer is no longer 468 * needed. In this case, callers are responsible for setting an embedded 469 * pointer to NULL if it is known that the last reference is being released. 470 * 471 * If the passed-in address of the smb_node pointer belongs to a local variable, 472 * then the caller with the local variable should call smb_node_release() 473 * directly. 474 * 475 * smb_node_release() itself will call smb_node_release() on a node's dir_snode, 476 * as smb_node_lookup() takes a hold on dir_snode. 477 */ 478 void 479 smb_node_release(smb_node_t *node) 480 { 481 SMB_NODE_VALID(node); 482 483 mutex_enter(&node->n_mutex); 484 ASSERT(node->n_refcnt); 485 DTRACE_PROBE1(smb_node_release, smb_node_t *, node); 486 if (--node->n_refcnt == 0) { 487 switch (node->n_state) { 488 489 case SMB_NODE_STATE_AVAILABLE: 490 node->n_state = SMB_NODE_STATE_DESTROYING; 491 mutex_exit(&node->n_mutex); 492 493 smb_llist_enter(node->n_hash_bucket, RW_WRITER); 494 smb_llist_remove(node->n_hash_bucket, node); 495 smb_llist_exit(node->n_hash_bucket); 496 497 /* 498 * Check if the file was deleted 499 */ 500 smb_node_delete_on_close(node); 501 502 if (node->dir_snode) { 503 ASSERT(node->dir_snode->n_magic == 504 SMB_NODE_MAGIC); 505 smb_node_release(node->dir_snode); 506 } 507 508 if (node->unnamed_stream_node) { 509 ASSERT(node->unnamed_stream_node->n_magic == 510 SMB_NODE_MAGIC); 511 smb_node_release(node->unnamed_stream_node); 512 } 513 514 smb_node_free(node); 515 return; 516 517 default: 518 SMB_PANIC(); 519 } 520 } 521 smb_node_audit(node); 522 mutex_exit(&node->n_mutex); 523 } 524 525 static void 526 smb_node_delete_on_close(smb_node_t *node) 527 { 528 smb_node_t *d_snode; 529 int rc = 0; 530 uint32_t flags = 0; 531 532 d_snode = node->dir_snode; 533 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 534 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE; 535 flags = node->n_delete_on_close_flags; 536 ASSERT(node->od_name != NULL); 537 538 if (node->vp->v_type == VDIR) 539 rc = smb_fsop_rmdir(0, node->delete_on_close_cred, 540 d_snode, node->od_name, flags); 541 else 542 rc = smb_fsop_remove(0, node->delete_on_close_cred, 543 d_snode, node->od_name, flags); 544 smb_cred_rele(node->delete_on_close_cred); 545 } 546 if (rc != 0) 547 cmn_err(CE_WARN, "File %s could not be removed, rc=%d\n", 548 node->od_name, rc); 549 DTRACE_PROBE2(smb_node_delete_on_close, int, rc, smb_node_t *, node); 550 } 551 552 /* 553 * smb_node_rename() 554 * 555 */ 556 void 557 smb_node_rename( 558 smb_node_t *from_dnode, 559 smb_node_t *ret_node, 560 smb_node_t *to_dnode, 561 char *to_name) 562 { 563 SMB_NODE_VALID(from_dnode); 564 SMB_NODE_VALID(to_dnode); 565 SMB_NODE_VALID(ret_node); 566 567 smb_node_ref(to_dnode); 568 mutex_enter(&ret_node->n_mutex); 569 switch (ret_node->n_state) { 570 case SMB_NODE_STATE_AVAILABLE: 571 case SMB_NODE_STATE_OPLOCK_GRANTED: 572 case SMB_NODE_STATE_OPLOCK_BREAKING: 573 ret_node->dir_snode = to_dnode; 574 mutex_exit(&ret_node->n_mutex); 575 ASSERT(to_dnode->dir_snode != ret_node); 576 ASSERT((to_dnode->vp->v_xattrdir) || 577 (to_dnode->vp->v_type == VDIR)); 578 smb_node_release(from_dnode); 579 (void) strcpy(ret_node->od_name, to_name); 580 /* 581 * XXX Need to update attributes? 582 */ 583 break; 584 default: 585 SMB_PANIC(); 586 } 587 } 588 589 int 590 smb_node_root_init(vnode_t *vp, smb_server_t *sv, smb_node_t **root) 591 { 592 smb_attr_t attr; 593 int error; 594 uint32_t hashkey; 595 smb_llist_t *node_hdr; 596 smb_node_t *node; 597 598 attr.sa_mask = SMB_AT_ALL; 599 error = smb_vop_getattr(vp, NULL, &attr, 0, kcred); 600 if (error) { 601 VN_RELE(vp); 602 return (error); 603 } 604 605 node_hdr = smb_node_get_hash(&vp->v_vfsp->vfs_fsid, &attr, &hashkey); 606 607 node = smb_node_alloc(ROOTVOL, vp, node_hdr, hashkey); 608 609 sv->si_root_smb_node = node; 610 smb_node_audit(node); 611 smb_llist_enter(node_hdr, RW_WRITER); 612 smb_llist_insert_head(node_hdr, node); 613 smb_llist_exit(node_hdr); 614 *root = node; 615 return (0); 616 } 617 618 /* 619 * When DeleteOnClose is set on an smb_node, the common open code will 620 * reject subsequent open requests for the file. Observation of Windows 621 * 2000 indicates that subsequent opens should be allowed (assuming 622 * there would be no sharing violation) until the file is closed using 623 * the fid on which the DeleteOnClose was requested. 624 * 625 * If there are multiple opens with delete-on-close create options, 626 * whichever the first file handle is closed will trigger the node to be 627 * marked as delete-on-close. The credentials of that ofile will be used 628 * as the delete-on-close credentials of the node. 629 */ 630 int 631 smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags) 632 { 633 int rc; 634 smb_attr_t attr; 635 636 mutex_enter(&node->n_mutex); 637 638 if ((node->flags & NODE_FLAGS_DELETE_ON_CLOSE) || 639 (node->readonly_creator)) { 640 mutex_exit(&node->n_mutex); 641 return (-1); 642 } 643 644 bzero(&attr, sizeof (smb_attr_t)); 645 attr.sa_mask = SMB_AT_DOSATTR; 646 rc = smb_fsop_getattr(NULL, kcred, node, &attr); 647 if ((rc != 0) || (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)) { 648 mutex_exit(&node->n_mutex); 649 return (-1); 650 } 651 652 crhold(cr); 653 node->delete_on_close_cred = cr; 654 node->n_delete_on_close_flags = flags; 655 node->flags |= NODE_FLAGS_DELETE_ON_CLOSE; 656 mutex_exit(&node->n_mutex); 657 return (0); 658 } 659 660 void 661 smb_node_reset_delete_on_close(smb_node_t *node) 662 { 663 mutex_enter(&node->n_mutex); 664 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 665 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE; 666 crfree(node->delete_on_close_cred); 667 node->delete_on_close_cred = NULL; 668 node->n_delete_on_close_flags = 0; 669 } 670 mutex_exit(&node->n_mutex); 671 } 672 673 /* 674 * smb_node_open_check 675 * 676 * check file sharing rules for current open request 677 * against all existing opens for a file. 678 * 679 * Returns NT_STATUS_SHARING_VIOLATION if there is any 680 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 681 */ 682 uint32_t 683 smb_node_open_check( 684 smb_node_t *node, 685 cred_t *cr, 686 uint32_t desired_access, 687 uint32_t share_access) 688 { 689 smb_ofile_t *of; 690 uint32_t status; 691 692 SMB_NODE_VALID(node); 693 694 smb_llist_enter(&node->n_ofile_list, RW_READER); 695 of = smb_llist_head(&node->n_ofile_list); 696 while (of) { 697 status = smb_ofile_open_check(of, cr, desired_access, 698 share_access); 699 700 switch (status) { 701 case NT_STATUS_INVALID_HANDLE: 702 case NT_STATUS_SUCCESS: 703 of = smb_llist_next(&node->n_ofile_list, of); 704 break; 705 default: 706 ASSERT(status == NT_STATUS_SHARING_VIOLATION); 707 smb_llist_exit(&node->n_ofile_list); 708 return (status); 709 } 710 } 711 712 smb_llist_exit(&node->n_ofile_list); 713 return (NT_STATUS_SUCCESS); 714 } 715 716 uint32_t 717 smb_node_rename_check(smb_node_t *node) 718 { 719 smb_ofile_t *of; 720 uint32_t status; 721 722 SMB_NODE_VALID(node); 723 724 /* 725 * Intra-CIFS check 726 */ 727 smb_llist_enter(&node->n_ofile_list, RW_READER); 728 of = smb_llist_head(&node->n_ofile_list); 729 while (of) { 730 status = smb_ofile_rename_check(of); 731 732 switch (status) { 733 case NT_STATUS_INVALID_HANDLE: 734 case NT_STATUS_SUCCESS: 735 of = smb_llist_next(&node->n_ofile_list, of); 736 break; 737 default: 738 ASSERT(status == NT_STATUS_SHARING_VIOLATION); 739 smb_llist_exit(&node->n_ofile_list); 740 return (status); 741 } 742 } 743 smb_llist_exit(&node->n_ofile_list); 744 745 /* 746 * system-wide share check 747 */ 748 if (nbl_share_conflict(node->vp, NBL_RENAME, NULL)) 749 return (NT_STATUS_SHARING_VIOLATION); 750 else 751 return (NT_STATUS_SUCCESS); 752 } 753 754 uint32_t 755 smb_node_delete_check(smb_node_t *node) 756 { 757 smb_ofile_t *of; 758 uint32_t status; 759 760 SMB_NODE_VALID(node); 761 762 if (node->vp->v_type == VDIR) 763 return (NT_STATUS_SUCCESS); 764 765 /* 766 * intra-CIFS check 767 */ 768 smb_llist_enter(&node->n_ofile_list, RW_READER); 769 of = smb_llist_head(&node->n_ofile_list); 770 while (of) { 771 status = smb_ofile_delete_check(of); 772 773 switch (status) { 774 case NT_STATUS_INVALID_HANDLE: 775 case NT_STATUS_SUCCESS: 776 of = smb_llist_next(&node->n_ofile_list, of); 777 break; 778 default: 779 ASSERT(status == NT_STATUS_SHARING_VIOLATION); 780 smb_llist_exit(&node->n_ofile_list); 781 return (status); 782 } 783 } 784 smb_llist_exit(&node->n_ofile_list); 785 786 /* 787 * system-wide share check 788 */ 789 if (nbl_share_conflict(node->vp, NBL_REMOVE, NULL)) 790 return (NT_STATUS_SHARING_VIOLATION); 791 else 792 return (NT_STATUS_SUCCESS); 793 } 794 795 void 796 smb_node_notify_change(smb_node_t *node) 797 { 798 SMB_NODE_VALID(node); 799 800 if (node->flags & NODE_FLAGS_NOTIFY_CHANGE) { 801 node->flags |= NODE_FLAGS_CHANGED; 802 smb_process_node_notify_change_queue(node); 803 } 804 } 805 806 /* 807 * smb_node_start_crit() 808 * 809 * Enter critical region for share reservations. 810 * See comments above smb_fsop_shrlock(). 811 */ 812 813 void 814 smb_node_start_crit(smb_node_t *node, krw_t mode) 815 { 816 rw_enter(&node->n_lock, mode); 817 nbl_start_crit(node->vp, mode); 818 } 819 820 /* 821 * smb_node_end_crit() 822 * 823 * Exit critical region for share reservations. 824 */ 825 826 void 827 smb_node_end_crit(smb_node_t *node) 828 { 829 nbl_end_crit(node->vp); 830 rw_exit(&node->n_lock); 831 } 832 833 int 834 smb_node_in_crit(smb_node_t *node) 835 { 836 return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_lock)); 837 } 838 839 void 840 smb_node_rdlock(smb_node_t *node) 841 { 842 rw_enter(&node->n_lock, RW_READER); 843 } 844 845 void 846 smb_node_wrlock(smb_node_t *node) 847 { 848 rw_enter(&node->n_lock, RW_WRITER); 849 } 850 851 void 852 smb_node_unlock(smb_node_t *node) 853 { 854 rw_exit(&node->n_lock); 855 } 856 857 uint32_t 858 smb_node_get_ofile_count(smb_node_t *node) 859 { 860 uint32_t cntr; 861 862 SMB_NODE_VALID(node); 863 864 smb_llist_enter(&node->n_ofile_list, RW_READER); 865 cntr = smb_llist_get_count(&node->n_ofile_list); 866 smb_llist_exit(&node->n_ofile_list); 867 return (cntr); 868 } 869 870 void 871 smb_node_add_ofile(smb_node_t *node, smb_ofile_t *of) 872 { 873 SMB_NODE_VALID(node); 874 875 smb_llist_enter(&node->n_ofile_list, RW_WRITER); 876 smb_llist_insert_tail(&node->n_ofile_list, of); 877 smb_llist_exit(&node->n_ofile_list); 878 } 879 880 void 881 smb_node_rem_ofile(smb_node_t *node, smb_ofile_t *of) 882 { 883 SMB_NODE_VALID(node); 884 885 smb_llist_enter(&node->n_ofile_list, RW_WRITER); 886 smb_llist_remove(&node->n_ofile_list, of); 887 smb_llist_exit(&node->n_ofile_list); 888 } 889 890 /* 891 * smb_node_inc_open_ofiles 892 */ 893 void 894 smb_node_inc_open_ofiles(smb_node_t *node) 895 { 896 SMB_NODE_VALID(node); 897 898 mutex_enter(&node->n_mutex); 899 node->n_open_count++; 900 mutex_exit(&node->n_mutex); 901 902 smb_node_init_cached_timestamps(node); 903 } 904 905 /* 906 * smb_node_dec_open_ofiles 907 */ 908 void 909 smb_node_dec_open_ofiles(smb_node_t *node) 910 { 911 SMB_NODE_VALID(node); 912 913 mutex_enter(&node->n_mutex); 914 node->n_open_count--; 915 mutex_exit(&node->n_mutex); 916 917 smb_node_clear_cached_timestamps(node); 918 } 919 920 uint32_t 921 smb_node_get_open_ofiles(smb_node_t *node) 922 { 923 uint32_t cnt; 924 925 SMB_NODE_VALID(node); 926 927 mutex_enter(&node->n_mutex); 928 cnt = node->n_open_count; 929 mutex_exit(&node->n_mutex); 930 return (cnt); 931 } 932 933 /* 934 * smb_node_alloc 935 */ 936 static smb_node_t * 937 smb_node_alloc( 938 char *od_name, 939 vnode_t *vp, 940 smb_llist_t *bucket, 941 uint32_t hashkey) 942 { 943 smb_node_t *node; 944 945 node = kmem_cache_alloc(smb_node_cache, KM_SLEEP); 946 947 if (node->n_audit_buf != NULL) 948 node->n_audit_buf->anb_index = 0; 949 950 node->flags = 0; 951 VN_HOLD(vp); 952 node->vp = vp; 953 node->n_refcnt = 1; 954 node->n_hash_bucket = bucket; 955 node->n_hashkey = hashkey; 956 node->n_orig_uid = 0; 957 node->readonly_creator = NULL; 958 node->waiting_event = 0; 959 node->what = 0; 960 node->n_open_count = 0; 961 node->dir_snode = NULL; 962 node->unnamed_stream_node = NULL; 963 node->delete_on_close_cred = NULL; 964 node->n_delete_on_close_flags = 0; 965 966 (void) strlcpy(node->od_name, od_name, sizeof (node->od_name)); 967 if (strcmp(od_name, XATTR_DIR) == 0) 968 node->flags |= NODE_XATTR_DIR; 969 970 node->n_state = SMB_NODE_STATE_AVAILABLE; 971 node->n_magic = SMB_NODE_MAGIC; 972 return (node); 973 } 974 975 /* 976 * smb_node_free 977 */ 978 static void 979 smb_node_free(smb_node_t *node) 980 { 981 SMB_NODE_VALID(node); 982 983 node->n_magic = 0; 984 VERIFY(!list_link_active(&node->n_lnd)); 985 VERIFY(node->n_lock_list.ll_count == 0); 986 VERIFY(node->n_ofile_list.ll_count == 0); 987 VERIFY(node->n_oplock.ol_xthread == NULL); 988 VERIFY(mutex_owner(&node->n_mutex) == NULL); 989 VERIFY(!RW_LOCK_HELD(&node->n_lock)); 990 VN_RELE(node->vp); 991 kmem_cache_free(smb_node_cache, node); 992 } 993 994 /* 995 * smb_node_constructor 996 */ 997 static int 998 smb_node_constructor(void *buf, void *un, int kmflags) 999 { 1000 _NOTE(ARGUNUSED(kmflags, un)) 1001 1002 smb_node_t *node = (smb_node_t *)buf; 1003 1004 bzero(node, sizeof (smb_node_t)); 1005 1006 smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t), 1007 offsetof(smb_ofile_t, f_nnd)); 1008 smb_llist_constructor(&node->n_lock_list, sizeof (smb_lock_t), 1009 offsetof(smb_lock_t, l_lnd)); 1010 cv_init(&node->n_oplock.ol_cv, NULL, CV_DEFAULT, NULL); 1011 rw_init(&node->n_lock, NULL, RW_DEFAULT, NULL); 1012 mutex_init(&node->n_mutex, NULL, MUTEX_DEFAULT, NULL); 1013 smb_node_create_audit_buf(node, kmflags); 1014 return (0); 1015 } 1016 1017 /* 1018 * smb_node_destructor 1019 */ 1020 static void 1021 smb_node_destructor(void *buf, void *un) 1022 { 1023 _NOTE(ARGUNUSED(un)) 1024 1025 smb_node_t *node = (smb_node_t *)buf; 1026 1027 smb_node_destroy_audit_buf(node); 1028 mutex_destroy(&node->n_mutex); 1029 rw_destroy(&node->n_lock); 1030 cv_destroy(&node->n_oplock.ol_cv); 1031 smb_llist_destructor(&node->n_lock_list); 1032 smb_llist_destructor(&node->n_ofile_list); 1033 } 1034 1035 /* 1036 * smb_node_create_audit_buf 1037 */ 1038 static void 1039 smb_node_create_audit_buf(smb_node_t *node, int kmflags) 1040 { 1041 smb_audit_buf_node_t *abn; 1042 1043 if (smb_audit_flags & SMB_AUDIT_NODE) { 1044 abn = kmem_zalloc(sizeof (smb_audit_buf_node_t), kmflags); 1045 abn->anb_max_index = SMB_AUDIT_BUF_MAX_REC - 1; 1046 node->n_audit_buf = abn; 1047 } 1048 } 1049 1050 /* 1051 * smb_node_destroy_audit_buf 1052 */ 1053 static void 1054 smb_node_destroy_audit_buf(smb_node_t *node) 1055 { 1056 if (node->n_audit_buf != NULL) { 1057 kmem_free(node->n_audit_buf, sizeof (smb_audit_buf_node_t)); 1058 node->n_audit_buf = NULL; 1059 } 1060 } 1061 1062 /* 1063 * smb_node_audit 1064 * 1065 * This function saves the calling stack in the audit buffer of the node passed 1066 * in. 1067 */ 1068 static void 1069 smb_node_audit(smb_node_t *node) 1070 { 1071 smb_audit_buf_node_t *abn; 1072 smb_audit_record_node_t *anr; 1073 1074 if (node->n_audit_buf) { 1075 abn = node->n_audit_buf; 1076 anr = abn->anb_records; 1077 anr += abn->anb_index; 1078 abn->anb_index++; 1079 abn->anb_index &= abn->anb_max_index; 1080 anr->anr_refcnt = node->n_refcnt; 1081 anr->anr_depth = getpcstack(anr->anr_stack, 1082 SMB_AUDIT_STACK_DEPTH); 1083 } 1084 } 1085 1086 static smb_llist_t * 1087 smb_node_get_hash(fsid_t *fsid, smb_attr_t *attr, uint32_t *phashkey) 1088 { 1089 uint32_t hashkey; 1090 1091 hashkey = fsid->val[0] + attr->sa_vattr.va_nodeid; 1092 hashkey += (hashkey >> 24) + (hashkey >> 16) + (hashkey >> 8); 1093 *phashkey = hashkey; 1094 return (&smb_node_hash_table[(hashkey & SMBND_HASH_MASK)]); 1095 } 1096 1097 boolean_t 1098 smb_node_is_dir(smb_node_t *node) 1099 { 1100 SMB_NODE_VALID(node); 1101 return (node->vp->v_type == VDIR); 1102 } 1103 1104 boolean_t 1105 smb_node_is_link(smb_node_t *node) 1106 { 1107 SMB_NODE_VALID(node); 1108 return (node->vp->v_type == VLNK); 1109 } 1110 1111 /* 1112 * smb_node_file_is_readonly 1113 * 1114 * Checks if the file (which node represents) is marked readonly 1115 * in the filesystem. No account is taken of any pending readonly 1116 * in the node, which must be handled by the callers. 1117 * (See SMB_OFILE_IS_READONLY and SMB_PATHFILE_IS_READONLY) 1118 */ 1119 boolean_t 1120 smb_node_file_is_readonly(smb_node_t *node) 1121 { 1122 smb_attr_t attr; 1123 1124 if (node == NULL) 1125 return (B_FALSE); 1126 1127 bzero(&attr, sizeof (smb_attr_t)); 1128 attr.sa_mask = SMB_AT_DOSATTR; 1129 (void) smb_fsop_getattr(NULL, kcred, node, &attr); 1130 return ((attr.sa_dosattr & FILE_ATTRIBUTE_READONLY) != 0); 1131 } 1132 1133 /* 1134 * smb_node_setattr 1135 * 1136 * The sr may be NULL, for example when closing an ofile. 1137 * The ofile may be NULL, for example when a client request 1138 * specifies the file by pathname. 1139 * 1140 * When attributes are set on an ofile, any pending timestamps 1141 * from a write request on the ofile are implicitly set to "now". 1142 * For compatibility with windows the following timestamps are 1143 * also implicitly set to now: 1144 * - if any attribute is being explicitly set, set ctime to now 1145 * - if file size is being explicitly set, set atime & ctime to now 1146 * 1147 * Any attribute that is being explicitly set, or has previously 1148 * been explicitly set on the ofile, is excluded from implicit 1149 * (now) setting. 1150 * 1151 * Updates the node's cached timestamp values. 1152 * Updates the ofile's explicit times flag. 1153 * 1154 * Returns: errno 1155 */ 1156 int 1157 smb_node_setattr(smb_request_t *sr, smb_node_t *node, 1158 cred_t *cr, smb_ofile_t *of, smb_attr_t *attr) 1159 { 1160 int rc; 1161 uint32_t what; 1162 uint32_t now_times = 0; 1163 timestruc_t now; 1164 1165 ASSERT(attr); 1166 SMB_NODE_VALID(node); 1167 1168 what = attr->sa_mask; 1169 1170 /* determine which timestamps to implicitly set to "now" */ 1171 if (what) 1172 now_times |= SMB_AT_CTIME; 1173 if (what & SMB_AT_SIZE) 1174 now_times |= (SMB_AT_MTIME | SMB_AT_CTIME); 1175 if (of) { 1176 if (smb_ofile_write_time_pending(of)) 1177 now_times |= 1178 (SMB_AT_MTIME | SMB_AT_CTIME | SMB_AT_ATIME); 1179 now_times &= ~(smb_ofile_explicit_times(of)); 1180 } 1181 now_times &= ~what; 1182 1183 if (now_times) { 1184 gethrestime(&now); 1185 1186 if (now_times & SMB_AT_ATIME) { 1187 attr->sa_vattr.va_atime = now; 1188 attr->sa_mask |= SMB_AT_ATIME; 1189 } 1190 if (now_times & SMB_AT_MTIME) { 1191 attr->sa_vattr.va_mtime = now; 1192 attr->sa_mask |= SMB_AT_MTIME; 1193 } 1194 if (now_times & SMB_AT_CTIME) { 1195 attr->sa_vattr.va_ctime = now; 1196 attr->sa_mask |= SMB_AT_CTIME; 1197 } 1198 } 1199 1200 if (attr->sa_mask == 0) 1201 return (0); 1202 1203 rc = smb_fsop_setattr(sr, cr, node, attr); 1204 if (rc != 0) 1205 return (rc); 1206 1207 smb_node_set_cached_timestamps(node, attr); 1208 1209 if (of) 1210 smb_ofile_set_explicit_times(of, (what & SMB_AT_TIMES)); 1211 1212 return (0); 1213 } 1214 1215 /* 1216 * smb_node_getattr 1217 * 1218 * Get attributes from the file system and apply any smb-specific 1219 * overrides for size, dos attributes and timestamps 1220 * 1221 * node->readonly_creator reflects whether a readonly set is pending 1222 * from a readonly create. The readonly attribute should be visible to 1223 * all clients even though the readonly creator fid is immune to the 1224 * readonly bit until close. 1225 * 1226 * Returns: errno 1227 */ 1228 int 1229 smb_node_getattr(smb_request_t *sr, smb_node_t *node, smb_attr_t *attr) 1230 { 1231 int rc; 1232 1233 SMB_NODE_VALID(node); 1234 1235 bzero(attr, sizeof (smb_attr_t)); 1236 attr->sa_mask = SMB_AT_ALL; 1237 rc = smb_fsop_getattr(sr, kcred, node, attr); 1238 if (rc != 0) 1239 return (rc); 1240 1241 mutex_enter(&node->n_mutex); 1242 1243 if (node->vp->v_type == VDIR) 1244 attr->sa_vattr.va_size = 0; 1245 1246 if (node->readonly_creator) 1247 attr->sa_dosattr |= FILE_ATTRIBUTE_READONLY; 1248 if (attr->sa_dosattr == 0) 1249 attr->sa_dosattr = FILE_ATTRIBUTE_NORMAL; 1250 1251 mutex_exit(&node->n_mutex); 1252 1253 smb_node_get_cached_timestamps(node, attr); 1254 return (0); 1255 } 1256 1257 /* 1258 * Timestamp caching 1259 * 1260 * Solaris file systems handle timestamps different from NTFS. For 1261 * example when file data is written NTFS doesn't update the timestamps 1262 * until the file is closed, and then only if they haven't been explicity 1263 * set via a set attribute request. In order to provide a more similar 1264 * view of an open file's timestamps, we cache the timestamps in the 1265 * node and manipulate them in a manner more consistent with windows. 1266 * (See handling of explicit times and pending timestamps from a write 1267 * request in smb_node_getattr and smb_node_setattr above.) 1268 * Timestamps remain cached while there are open ofiles for the node. 1269 * This includes open ofiles for named streams. 1270 * n_open_ofiles cannot be used as this doesn't include ofiles opened 1271 * for the node's named streams. Thus n_timestamps contains a count 1272 * of open ofiles (t_open_ofiles), including named streams' ofiles, 1273 * to be used to control timestamp caching. 1274 * 1275 * If a node represents a named stream the associated unnamed streams 1276 * cached timestamps are used instead. 1277 */ 1278 1279 /* 1280 * smb_node_init_cached_timestamps 1281 * 1282 * Increment count of open ofiles which are using the cached timestamps. 1283 * If this is the first open ofile, init the cached timestamps from the 1284 * file system values. 1285 */ 1286 static void 1287 smb_node_init_cached_timestamps(smb_node_t *node) 1288 { 1289 smb_node_t *unode; 1290 smb_attr_t attr; 1291 1292 if ((unode = SMB_IS_STREAM(node)) != NULL) 1293 node = unode; 1294 1295 mutex_enter(&node->n_mutex); 1296 ++(node->n_timestamps.t_open_ofiles); 1297 if (node->n_timestamps.t_open_ofiles == 1) { 1298 bzero(&attr, sizeof (smb_attr_t)); 1299 attr.sa_mask = SMB_AT_TIMES; 1300 (void) smb_fsop_getattr(NULL, kcred, node, &attr); 1301 node->n_timestamps.t_mtime = attr.sa_vattr.va_mtime; 1302 node->n_timestamps.t_atime = attr.sa_vattr.va_atime; 1303 node->n_timestamps.t_ctime = attr.sa_vattr.va_ctime; 1304 node->n_timestamps.t_crtime = attr.sa_crtime; 1305 node->n_timestamps.t_cached = B_TRUE; 1306 } 1307 mutex_exit(&node->n_mutex); 1308 } 1309 1310 /* 1311 * smb_node_clear_cached_timestamps 1312 * 1313 * Decrement count of open ofiles using the cached timestamps. 1314 * If the decremented count is zero, clear the cached timestamps. 1315 */ 1316 static void 1317 smb_node_clear_cached_timestamps(smb_node_t *node) 1318 { 1319 smb_node_t *unode; 1320 1321 if ((unode = SMB_IS_STREAM(node)) != NULL) 1322 node = unode; 1323 1324 mutex_enter(&node->n_mutex); 1325 ASSERT(node->n_timestamps.t_open_ofiles > 0); 1326 --(node->n_timestamps.t_open_ofiles); 1327 if (node->n_timestamps.t_open_ofiles == 0) 1328 bzero(&node->n_timestamps, sizeof (smb_times_t)); 1329 mutex_exit(&node->n_mutex); 1330 } 1331 1332 /* 1333 * smb_node_get_cached_timestamps 1334 * 1335 * Overwrite timestamps in attr with those cached in node. 1336 */ 1337 static void 1338 smb_node_get_cached_timestamps(smb_node_t *node, smb_attr_t *attr) 1339 { 1340 smb_node_t *unode; 1341 1342 if ((unode = SMB_IS_STREAM(node)) != NULL) 1343 node = unode; 1344 1345 mutex_enter(&node->n_mutex); 1346 if (node->n_timestamps.t_cached) { 1347 attr->sa_vattr.va_mtime = node->n_timestamps.t_mtime; 1348 attr->sa_vattr.va_atime = node->n_timestamps.t_atime; 1349 attr->sa_vattr.va_ctime = node->n_timestamps.t_ctime; 1350 attr->sa_crtime = node->n_timestamps.t_crtime; 1351 } 1352 mutex_exit(&node->n_mutex); 1353 } 1354 1355 /* 1356 * smb_node_set_cached_timestamps 1357 * 1358 * Update the node's cached timestamps with values from attr. 1359 */ 1360 static void 1361 smb_node_set_cached_timestamps(smb_node_t *node, smb_attr_t *attr) 1362 { 1363 smb_node_t *unode; 1364 1365 if ((unode = SMB_IS_STREAM(node)) != NULL) 1366 node = unode; 1367 1368 mutex_enter(&node->n_mutex); 1369 if (node->n_timestamps.t_cached) { 1370 if (attr->sa_mask & SMB_AT_MTIME) 1371 node->n_timestamps.t_mtime = attr->sa_vattr.va_mtime; 1372 if (attr->sa_mask & SMB_AT_ATIME) 1373 node->n_timestamps.t_atime = attr->sa_vattr.va_atime; 1374 if (attr->sa_mask & SMB_AT_CTIME) 1375 node->n_timestamps.t_ctime = attr->sa_vattr.va_ctime; 1376 if (attr->sa_mask & SMB_AT_CRTIME) 1377 node->n_timestamps.t_crtime = attr->sa_crtime; 1378 } 1379 mutex_exit(&node->n_mutex); 1380 } 1381