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_)->n_dnode != (_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 * dnode (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 *dnode, 263 smb_node_t *unode) 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 (unode) 281 unnamed_vp = unode->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->n_dnode == NULL) && 327 (dnode != NULL) && 328 (strcmp(od_name, "..") != 0) && 329 (strcmp(od_name, ".") != 0)) { 330 VALIDATE_DIR_NODE(dnode, node); 331 node->n_dnode = dnode; 332 smb_node_ref(dnode); 333 } 334 335 smb_node_audit(node); 336 mutex_exit(&node->n_mutex); 337 smb_llist_exit(node_hdr); 338 return (node); 339 340 case SMB_NODE_STATE_DESTROYING: 341 /* 342 * Although the node exists it is about 343 * to be destroyed. We act as it hasn't 344 * been found. 345 */ 346 mutex_exit(&node->n_mutex); 347 break; 348 default: 349 /* 350 * Although the node exists it is in an 351 * unknown state. We act as it hasn't 352 * been found. 353 */ 354 ASSERT(0); 355 mutex_exit(&node->n_mutex); 356 break; 357 } 358 } 359 node = smb_llist_next(node_hdr, node); 360 } 361 if ((lock_mode == RW_READER) && smb_llist_upgrade(node_hdr)) { 362 lock_mode = RW_WRITER; 363 continue; 364 } 365 break; 366 } 367 node = smb_node_alloc(od_name, vp, node_hdr, hashkey); 368 node->n_orig_uid = crgetuid(sr->user_cr); 369 370 if (op) 371 node->flags |= smb_is_executable(op->fqi.fq_last_comp); 372 373 if (dnode) { 374 smb_node_ref(dnode); 375 node->n_dnode = dnode; 376 ASSERT(dnode->n_dnode != node); 377 ASSERT((dnode->vp->v_xattrdir) || 378 (dnode->vp->v_type == VDIR)); 379 } 380 381 if (unode) { 382 smb_node_ref(unode); 383 node->n_unode = unode; 384 } 385 386 DTRACE_PROBE1(smb_node_lookup_miss, smb_node_t *, node); 387 smb_node_audit(node); 388 smb_llist_insert_head(node_hdr, node); 389 smb_llist_exit(node_hdr); 390 return (node); 391 } 392 393 /* 394 * smb_stream_node_lookup() 395 * 396 * Note: stream_name (the name that will be stored in the "od_name" field 397 * of a stream's smb_node) is the same as the on-disk name for the stream 398 * except that it does not have SMB_STREAM_PREFIX prepended. 399 */ 400 401 smb_node_t * 402 smb_stream_node_lookup(smb_request_t *sr, cred_t *cr, smb_node_t *fnode, 403 vnode_t *xattrdirvp, vnode_t *vp, char *stream_name) 404 { 405 smb_node_t *xattrdir_node; 406 smb_node_t *snode; 407 408 xattrdir_node = smb_node_lookup(sr, NULL, cr, xattrdirvp, XATTR_DIR, 409 fnode, NULL); 410 411 if (xattrdir_node == NULL) 412 return (NULL); 413 414 snode = smb_node_lookup(sr, NULL, cr, vp, stream_name, xattrdir_node, 415 fnode); 416 417 (void) smb_node_release(xattrdir_node); 418 return (snode); 419 } 420 421 422 /* 423 * This function should be called whenever a reference is needed on an 424 * smb_node pointer. The copy of an smb_node pointer from one non-local 425 * data structure to another requires a reference to be taken on the smb_node 426 * (unless the usage is localized). Each data structure deallocation routine 427 * will call smb_node_release() on its smb_node pointers. 428 * 429 * In general, an smb_node pointer residing in a structure should never be 430 * stale. A node pointer may be NULL, however, and care should be taken 431 * prior to calling smb_node_ref(), which ASSERTs that the pointer is valid. 432 * Care also needs to be taken with respect to racing deallocations of a 433 * structure. 434 */ 435 void 436 smb_node_ref(smb_node_t *node) 437 { 438 SMB_NODE_VALID(node); 439 440 mutex_enter(&node->n_mutex); 441 switch (node->n_state) { 442 case SMB_NODE_STATE_AVAILABLE: 443 case SMB_NODE_STATE_OPLOCK_GRANTED: 444 case SMB_NODE_STATE_OPLOCK_BREAKING: 445 node->n_refcnt++; 446 ASSERT(node->n_refcnt); 447 DTRACE_PROBE1(smb_node_ref_exit, smb_node_t *, node); 448 smb_node_audit(node); 449 break; 450 default: 451 SMB_PANIC(); 452 } 453 mutex_exit(&node->n_mutex); 454 } 455 456 /* 457 * smb_node_lookup() takes a hold on an smb_node, whether found in the 458 * hash table or newly created. This hold is expected to be released 459 * in the following manner. 460 * 461 * smb_node_lookup() takes an address of an smb_node pointer. This should 462 * be getting passed down via a lookup (whether path name or component), mkdir, 463 * create. If the original smb_node pointer resides in a data structure, then 464 * the deallocation routine for the data structure is responsible for calling 465 * smb_node_release() on the smb_node pointer. Alternatively, 466 * smb_node_release() can be called as soon as the smb_node pointer is no longer 467 * needed. In this case, callers are responsible for setting an embedded 468 * pointer to NULL if it is known that the last reference is being released. 469 * 470 * If the passed-in address of the smb_node pointer belongs to a local variable, 471 * then the caller with the local variable should call smb_node_release() 472 * directly. 473 * 474 * smb_node_release() itself will call smb_node_release() on a node's n_dnode, 475 * as smb_node_lookup() takes a hold on dnode. 476 */ 477 void 478 smb_node_release(smb_node_t *node) 479 { 480 SMB_NODE_VALID(node); 481 482 mutex_enter(&node->n_mutex); 483 ASSERT(node->n_refcnt); 484 DTRACE_PROBE1(smb_node_release, smb_node_t *, node); 485 if (--node->n_refcnt == 0) { 486 switch (node->n_state) { 487 488 case SMB_NODE_STATE_AVAILABLE: 489 node->n_state = SMB_NODE_STATE_DESTROYING; 490 mutex_exit(&node->n_mutex); 491 492 smb_llist_enter(node->n_hash_bucket, RW_WRITER); 493 smb_llist_remove(node->n_hash_bucket, node); 494 smb_llist_exit(node->n_hash_bucket); 495 496 /* 497 * Check if the file was deleted 498 */ 499 smb_node_delete_on_close(node); 500 501 if (node->n_dnode) { 502 ASSERT(node->n_dnode->n_magic == 503 SMB_NODE_MAGIC); 504 smb_node_release(node->n_dnode); 505 } 506 507 if (node->n_unode) { 508 ASSERT(node->n_unode->n_magic == 509 SMB_NODE_MAGIC); 510 smb_node_release(node->n_unode); 511 } 512 513 smb_node_free(node); 514 return; 515 516 default: 517 SMB_PANIC(); 518 } 519 } 520 smb_node_audit(node); 521 mutex_exit(&node->n_mutex); 522 } 523 524 static void 525 smb_node_delete_on_close(smb_node_t *node) 526 { 527 smb_node_t *d_snode; 528 int rc = 0; 529 uint32_t flags = 0; 530 531 d_snode = node->n_dnode; 532 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 533 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE; 534 flags = node->n_delete_on_close_flags; 535 ASSERT(node->od_name != NULL); 536 537 if (node->vp->v_type == VDIR) 538 rc = smb_fsop_rmdir(0, node->delete_on_close_cred, 539 d_snode, node->od_name, flags); 540 else 541 rc = smb_fsop_remove(0, node->delete_on_close_cred, 542 d_snode, node->od_name, flags); 543 smb_cred_rele(node->delete_on_close_cred); 544 } 545 if (rc != 0) 546 cmn_err(CE_WARN, "File %s could not be removed, rc=%d\n", 547 node->od_name, rc); 548 DTRACE_PROBE2(smb_node_delete_on_close, int, rc, smb_node_t *, node); 549 } 550 551 /* 552 * smb_node_rename() 553 * 554 */ 555 void 556 smb_node_rename( 557 smb_node_t *from_dnode, 558 smb_node_t *ret_node, 559 smb_node_t *to_dnode, 560 char *to_name) 561 { 562 SMB_NODE_VALID(from_dnode); 563 SMB_NODE_VALID(to_dnode); 564 SMB_NODE_VALID(ret_node); 565 566 smb_node_ref(to_dnode); 567 mutex_enter(&ret_node->n_mutex); 568 switch (ret_node->n_state) { 569 case SMB_NODE_STATE_AVAILABLE: 570 case SMB_NODE_STATE_OPLOCK_GRANTED: 571 case SMB_NODE_STATE_OPLOCK_BREAKING: 572 ret_node->n_dnode = to_dnode; 573 mutex_exit(&ret_node->n_mutex); 574 ASSERT(to_dnode->n_dnode != ret_node); 575 ASSERT((to_dnode->vp->v_xattrdir) || 576 (to_dnode->vp->v_type == VDIR)); 577 smb_node_release(from_dnode); 578 (void) strcpy(ret_node->od_name, to_name); 579 /* 580 * XXX Need to update attributes? 581 */ 582 break; 583 default: 584 SMB_PANIC(); 585 } 586 } 587 588 int 589 smb_node_root_init(vnode_t *vp, smb_server_t *sv, smb_node_t **root) 590 { 591 smb_attr_t attr; 592 int error; 593 uint32_t hashkey; 594 smb_llist_t *node_hdr; 595 smb_node_t *node; 596 597 attr.sa_mask = SMB_AT_ALL; 598 error = smb_vop_getattr(vp, NULL, &attr, 0, kcred); 599 if (error) { 600 VN_RELE(vp); 601 return (error); 602 } 603 604 node_hdr = smb_node_get_hash(&vp->v_vfsp->vfs_fsid, &attr, &hashkey); 605 606 node = smb_node_alloc(ROOTVOL, vp, node_hdr, hashkey); 607 608 sv->si_root_smb_node = node; 609 smb_node_audit(node); 610 smb_llist_enter(node_hdr, RW_WRITER); 611 smb_llist_insert_head(node_hdr, node); 612 smb_llist_exit(node_hdr); 613 *root = node; 614 return (0); 615 } 616 617 /* 618 * When DeleteOnClose is set on an smb_node, the common open code will 619 * reject subsequent open requests for the file. Observation of Windows 620 * 2000 indicates that subsequent opens should be allowed (assuming 621 * there would be no sharing violation) until the file is closed using 622 * the fid on which the DeleteOnClose was requested. 623 * 624 * If there are multiple opens with delete-on-close create options, 625 * whichever the first file handle is closed will trigger the node to be 626 * marked as delete-on-close. The credentials of that ofile will be used 627 * as the delete-on-close credentials of the node. 628 */ 629 int 630 smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags) 631 { 632 int rc; 633 smb_attr_t attr; 634 635 mutex_enter(&node->n_mutex); 636 637 if ((node->flags & NODE_FLAGS_DELETE_ON_CLOSE) || 638 (node->readonly_creator)) { 639 mutex_exit(&node->n_mutex); 640 return (-1); 641 } 642 643 bzero(&attr, sizeof (smb_attr_t)); 644 attr.sa_mask = SMB_AT_DOSATTR; 645 rc = smb_fsop_getattr(NULL, kcred, node, &attr); 646 if ((rc != 0) || (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)) { 647 mutex_exit(&node->n_mutex); 648 return (-1); 649 } 650 651 crhold(cr); 652 node->delete_on_close_cred = cr; 653 node->n_delete_on_close_flags = flags; 654 node->flags |= NODE_FLAGS_DELETE_ON_CLOSE; 655 mutex_exit(&node->n_mutex); 656 return (0); 657 } 658 659 void 660 smb_node_reset_delete_on_close(smb_node_t *node) 661 { 662 mutex_enter(&node->n_mutex); 663 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 664 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE; 665 crfree(node->delete_on_close_cred); 666 node->delete_on_close_cred = NULL; 667 node->n_delete_on_close_flags = 0; 668 } 669 mutex_exit(&node->n_mutex); 670 } 671 672 /* 673 * smb_node_open_check 674 * 675 * check file sharing rules for current open request 676 * against all existing opens for a file. 677 * 678 * Returns NT_STATUS_SHARING_VIOLATION if there is any 679 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 680 */ 681 uint32_t 682 smb_node_open_check( 683 smb_node_t *node, 684 cred_t *cr, 685 uint32_t desired_access, 686 uint32_t share_access) 687 { 688 smb_ofile_t *of; 689 uint32_t status; 690 691 SMB_NODE_VALID(node); 692 693 smb_llist_enter(&node->n_ofile_list, RW_READER); 694 of = smb_llist_head(&node->n_ofile_list); 695 while (of) { 696 status = smb_ofile_open_check(of, cr, desired_access, 697 share_access); 698 699 switch (status) { 700 case NT_STATUS_INVALID_HANDLE: 701 case NT_STATUS_SUCCESS: 702 of = smb_llist_next(&node->n_ofile_list, of); 703 break; 704 default: 705 ASSERT(status == NT_STATUS_SHARING_VIOLATION); 706 smb_llist_exit(&node->n_ofile_list); 707 return (status); 708 } 709 } 710 711 smb_llist_exit(&node->n_ofile_list); 712 return (NT_STATUS_SUCCESS); 713 } 714 715 uint32_t 716 smb_node_rename_check(smb_node_t *node) 717 { 718 smb_ofile_t *of; 719 uint32_t status; 720 721 SMB_NODE_VALID(node); 722 723 /* 724 * Intra-CIFS check 725 */ 726 smb_llist_enter(&node->n_ofile_list, RW_READER); 727 of = smb_llist_head(&node->n_ofile_list); 728 while (of) { 729 status = smb_ofile_rename_check(of); 730 731 switch (status) { 732 case NT_STATUS_INVALID_HANDLE: 733 case NT_STATUS_SUCCESS: 734 of = smb_llist_next(&node->n_ofile_list, of); 735 break; 736 default: 737 ASSERT(status == NT_STATUS_SHARING_VIOLATION); 738 smb_llist_exit(&node->n_ofile_list); 739 return (status); 740 } 741 } 742 smb_llist_exit(&node->n_ofile_list); 743 744 /* 745 * system-wide share check 746 */ 747 if (nbl_share_conflict(node->vp, NBL_RENAME, NULL)) 748 return (NT_STATUS_SHARING_VIOLATION); 749 else 750 return (NT_STATUS_SUCCESS); 751 } 752 753 uint32_t 754 smb_node_delete_check(smb_node_t *node) 755 { 756 smb_ofile_t *of; 757 uint32_t status; 758 759 SMB_NODE_VALID(node); 760 761 if (node->vp->v_type == VDIR) 762 return (NT_STATUS_SUCCESS); 763 764 /* 765 * intra-CIFS check 766 */ 767 smb_llist_enter(&node->n_ofile_list, RW_READER); 768 of = smb_llist_head(&node->n_ofile_list); 769 while (of) { 770 status = smb_ofile_delete_check(of); 771 772 switch (status) { 773 case NT_STATUS_INVALID_HANDLE: 774 case NT_STATUS_SUCCESS: 775 of = smb_llist_next(&node->n_ofile_list, of); 776 break; 777 default: 778 ASSERT(status == NT_STATUS_SHARING_VIOLATION); 779 smb_llist_exit(&node->n_ofile_list); 780 return (status); 781 } 782 } 783 smb_llist_exit(&node->n_ofile_list); 784 785 /* 786 * system-wide share check 787 */ 788 if (nbl_share_conflict(node->vp, NBL_REMOVE, NULL)) 789 return (NT_STATUS_SHARING_VIOLATION); 790 else 791 return (NT_STATUS_SUCCESS); 792 } 793 794 void 795 smb_node_notify_change(smb_node_t *node) 796 { 797 SMB_NODE_VALID(node); 798 799 if (node->flags & NODE_FLAGS_NOTIFY_CHANGE) { 800 node->flags |= NODE_FLAGS_CHANGED; 801 smb_process_node_notify_change_queue(node); 802 } 803 } 804 805 /* 806 * smb_node_start_crit() 807 * 808 * Enter critical region for share reservations. 809 * See comments above smb_fsop_shrlock(). 810 */ 811 812 void 813 smb_node_start_crit(smb_node_t *node, krw_t mode) 814 { 815 rw_enter(&node->n_lock, mode); 816 nbl_start_crit(node->vp, mode); 817 } 818 819 /* 820 * smb_node_end_crit() 821 * 822 * Exit critical region for share reservations. 823 */ 824 825 void 826 smb_node_end_crit(smb_node_t *node) 827 { 828 nbl_end_crit(node->vp); 829 rw_exit(&node->n_lock); 830 } 831 832 int 833 smb_node_in_crit(smb_node_t *node) 834 { 835 return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_lock)); 836 } 837 838 void 839 smb_node_rdlock(smb_node_t *node) 840 { 841 rw_enter(&node->n_lock, RW_READER); 842 } 843 844 void 845 smb_node_wrlock(smb_node_t *node) 846 { 847 rw_enter(&node->n_lock, RW_WRITER); 848 } 849 850 void 851 smb_node_unlock(smb_node_t *node) 852 { 853 rw_exit(&node->n_lock); 854 } 855 856 uint32_t 857 smb_node_get_ofile_count(smb_node_t *node) 858 { 859 uint32_t cntr; 860 861 SMB_NODE_VALID(node); 862 863 smb_llist_enter(&node->n_ofile_list, RW_READER); 864 cntr = smb_llist_get_count(&node->n_ofile_list); 865 smb_llist_exit(&node->n_ofile_list); 866 return (cntr); 867 } 868 869 void 870 smb_node_add_ofile(smb_node_t *node, smb_ofile_t *of) 871 { 872 SMB_NODE_VALID(node); 873 874 smb_llist_enter(&node->n_ofile_list, RW_WRITER); 875 smb_llist_insert_tail(&node->n_ofile_list, of); 876 smb_llist_exit(&node->n_ofile_list); 877 } 878 879 void 880 smb_node_rem_ofile(smb_node_t *node, smb_ofile_t *of) 881 { 882 SMB_NODE_VALID(node); 883 884 smb_llist_enter(&node->n_ofile_list, RW_WRITER); 885 smb_llist_remove(&node->n_ofile_list, of); 886 smb_llist_exit(&node->n_ofile_list); 887 } 888 889 /* 890 * smb_node_inc_open_ofiles 891 */ 892 void 893 smb_node_inc_open_ofiles(smb_node_t *node) 894 { 895 SMB_NODE_VALID(node); 896 897 mutex_enter(&node->n_mutex); 898 node->n_open_count++; 899 mutex_exit(&node->n_mutex); 900 901 smb_node_init_cached_timestamps(node); 902 } 903 904 /* 905 * smb_node_dec_open_ofiles 906 */ 907 void 908 smb_node_dec_open_ofiles(smb_node_t *node) 909 { 910 SMB_NODE_VALID(node); 911 912 mutex_enter(&node->n_mutex); 913 node->n_open_count--; 914 mutex_exit(&node->n_mutex); 915 916 smb_node_clear_cached_timestamps(node); 917 } 918 919 uint32_t 920 smb_node_get_open_ofiles(smb_node_t *node) 921 { 922 uint32_t cnt; 923 924 SMB_NODE_VALID(node); 925 926 mutex_enter(&node->n_mutex); 927 cnt = node->n_open_count; 928 mutex_exit(&node->n_mutex); 929 return (cnt); 930 } 931 932 /* 933 * smb_node_alloc 934 */ 935 static smb_node_t * 936 smb_node_alloc( 937 char *od_name, 938 vnode_t *vp, 939 smb_llist_t *bucket, 940 uint32_t hashkey) 941 { 942 smb_node_t *node; 943 944 node = kmem_cache_alloc(smb_node_cache, KM_SLEEP); 945 946 if (node->n_audit_buf != NULL) 947 node->n_audit_buf->anb_index = 0; 948 949 node->flags = 0; 950 VN_HOLD(vp); 951 node->vp = vp; 952 node->n_refcnt = 1; 953 node->n_hash_bucket = bucket; 954 node->n_hashkey = hashkey; 955 node->n_orig_uid = 0; 956 node->readonly_creator = NULL; 957 node->waiting_event = 0; 958 node->n_open_count = 0; 959 node->n_dnode = NULL; 960 node->n_unode = NULL; 961 node->delete_on_close_cred = NULL; 962 node->n_delete_on_close_flags = 0; 963 964 (void) strlcpy(node->od_name, od_name, sizeof (node->od_name)); 965 if (strcmp(od_name, XATTR_DIR) == 0) 966 node->flags |= NODE_XATTR_DIR; 967 968 node->n_state = SMB_NODE_STATE_AVAILABLE; 969 node->n_magic = SMB_NODE_MAGIC; 970 return (node); 971 } 972 973 /* 974 * smb_node_free 975 */ 976 static void 977 smb_node_free(smb_node_t *node) 978 { 979 SMB_NODE_VALID(node); 980 981 node->n_magic = 0; 982 VERIFY(!list_link_active(&node->n_lnd)); 983 VERIFY(node->n_lock_list.ll_count == 0); 984 VERIFY(node->n_ofile_list.ll_count == 0); 985 VERIFY(node->n_oplock.ol_xthread == NULL); 986 VERIFY(mutex_owner(&node->n_mutex) == NULL); 987 VERIFY(!RW_LOCK_HELD(&node->n_lock)); 988 VN_RELE(node->vp); 989 kmem_cache_free(smb_node_cache, node); 990 } 991 992 /* 993 * smb_node_constructor 994 */ 995 static int 996 smb_node_constructor(void *buf, void *un, int kmflags) 997 { 998 _NOTE(ARGUNUSED(kmflags, un)) 999 1000 smb_node_t *node = (smb_node_t *)buf; 1001 1002 bzero(node, sizeof (smb_node_t)); 1003 1004 smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t), 1005 offsetof(smb_ofile_t, f_nnd)); 1006 smb_llist_constructor(&node->n_lock_list, sizeof (smb_lock_t), 1007 offsetof(smb_lock_t, l_lnd)); 1008 cv_init(&node->n_oplock.ol_cv, NULL, CV_DEFAULT, NULL); 1009 rw_init(&node->n_lock, NULL, RW_DEFAULT, NULL); 1010 mutex_init(&node->n_mutex, NULL, MUTEX_DEFAULT, NULL); 1011 smb_node_create_audit_buf(node, kmflags); 1012 return (0); 1013 } 1014 1015 /* 1016 * smb_node_destructor 1017 */ 1018 static void 1019 smb_node_destructor(void *buf, void *un) 1020 { 1021 _NOTE(ARGUNUSED(un)) 1022 1023 smb_node_t *node = (smb_node_t *)buf; 1024 1025 smb_node_destroy_audit_buf(node); 1026 mutex_destroy(&node->n_mutex); 1027 rw_destroy(&node->n_lock); 1028 cv_destroy(&node->n_oplock.ol_cv); 1029 smb_llist_destructor(&node->n_lock_list); 1030 smb_llist_destructor(&node->n_ofile_list); 1031 } 1032 1033 /* 1034 * smb_node_create_audit_buf 1035 */ 1036 static void 1037 smb_node_create_audit_buf(smb_node_t *node, int kmflags) 1038 { 1039 smb_audit_buf_node_t *abn; 1040 1041 if (smb_audit_flags & SMB_AUDIT_NODE) { 1042 abn = kmem_zalloc(sizeof (smb_audit_buf_node_t), kmflags); 1043 abn->anb_max_index = SMB_AUDIT_BUF_MAX_REC - 1; 1044 node->n_audit_buf = abn; 1045 } 1046 } 1047 1048 /* 1049 * smb_node_destroy_audit_buf 1050 */ 1051 static void 1052 smb_node_destroy_audit_buf(smb_node_t *node) 1053 { 1054 if (node->n_audit_buf != NULL) { 1055 kmem_free(node->n_audit_buf, sizeof (smb_audit_buf_node_t)); 1056 node->n_audit_buf = NULL; 1057 } 1058 } 1059 1060 /* 1061 * smb_node_audit 1062 * 1063 * This function saves the calling stack in the audit buffer of the node passed 1064 * in. 1065 */ 1066 static void 1067 smb_node_audit(smb_node_t *node) 1068 { 1069 smb_audit_buf_node_t *abn; 1070 smb_audit_record_node_t *anr; 1071 1072 if (node->n_audit_buf) { 1073 abn = node->n_audit_buf; 1074 anr = abn->anb_records; 1075 anr += abn->anb_index; 1076 abn->anb_index++; 1077 abn->anb_index &= abn->anb_max_index; 1078 anr->anr_refcnt = node->n_refcnt; 1079 anr->anr_depth = getpcstack(anr->anr_stack, 1080 SMB_AUDIT_STACK_DEPTH); 1081 } 1082 } 1083 1084 static smb_llist_t * 1085 smb_node_get_hash(fsid_t *fsid, smb_attr_t *attr, uint32_t *phashkey) 1086 { 1087 uint32_t hashkey; 1088 1089 hashkey = fsid->val[0] + attr->sa_vattr.va_nodeid; 1090 hashkey += (hashkey >> 24) + (hashkey >> 16) + (hashkey >> 8); 1091 *phashkey = hashkey; 1092 return (&smb_node_hash_table[(hashkey & SMBND_HASH_MASK)]); 1093 } 1094 1095 boolean_t 1096 smb_node_is_dir(smb_node_t *node) 1097 { 1098 SMB_NODE_VALID(node); 1099 return (node->vp->v_type == VDIR); 1100 } 1101 1102 boolean_t 1103 smb_node_is_link(smb_node_t *node) 1104 { 1105 SMB_NODE_VALID(node); 1106 return (node->vp->v_type == VLNK); 1107 } 1108 1109 /* 1110 * smb_node_file_is_readonly 1111 * 1112 * Checks if the file (which node represents) is marked readonly 1113 * in the filesystem. No account is taken of any pending readonly 1114 * in the node, which must be handled by the callers. 1115 * (See SMB_OFILE_IS_READONLY and SMB_PATHFILE_IS_READONLY) 1116 */ 1117 boolean_t 1118 smb_node_file_is_readonly(smb_node_t *node) 1119 { 1120 smb_attr_t attr; 1121 1122 if (node == NULL) 1123 return (B_FALSE); 1124 1125 bzero(&attr, sizeof (smb_attr_t)); 1126 attr.sa_mask = SMB_AT_DOSATTR; 1127 (void) smb_fsop_getattr(NULL, kcred, node, &attr); 1128 return ((attr.sa_dosattr & FILE_ATTRIBUTE_READONLY) != 0); 1129 } 1130 1131 /* 1132 * smb_node_setattr 1133 * 1134 * The sr may be NULL, for example when closing an ofile. 1135 * The ofile may be NULL, for example when a client request 1136 * specifies the file by pathname. 1137 * 1138 * When attributes are set on an ofile, any pending timestamps 1139 * from a write request on the ofile are implicitly set to "now". 1140 * For compatibility with windows the following timestamps are 1141 * also implicitly set to now: 1142 * - if any attribute is being explicitly set, set ctime to now 1143 * - if file size is being explicitly set, set atime & ctime to now 1144 * 1145 * Any attribute that is being explicitly set, or has previously 1146 * been explicitly set on the ofile, is excluded from implicit 1147 * (now) setting. 1148 * 1149 * Updates the node's cached timestamp values. 1150 * Updates the ofile's explicit times flag. 1151 * 1152 * Returns: errno 1153 */ 1154 int 1155 smb_node_setattr(smb_request_t *sr, smb_node_t *node, 1156 cred_t *cr, smb_ofile_t *of, smb_attr_t *attr) 1157 { 1158 int rc; 1159 uint32_t what; 1160 uint32_t now_times = 0; 1161 timestruc_t now; 1162 1163 ASSERT(attr); 1164 SMB_NODE_VALID(node); 1165 1166 what = attr->sa_mask; 1167 1168 /* determine which timestamps to implicitly set to "now" */ 1169 if (what) 1170 now_times |= SMB_AT_CTIME; 1171 if (what & SMB_AT_SIZE) 1172 now_times |= (SMB_AT_MTIME | SMB_AT_CTIME); 1173 if (of) { 1174 if (smb_ofile_write_time_pending(of)) 1175 now_times |= 1176 (SMB_AT_MTIME | SMB_AT_CTIME | SMB_AT_ATIME); 1177 now_times &= ~(smb_ofile_explicit_times(of)); 1178 } 1179 now_times &= ~what; 1180 1181 if (now_times) { 1182 gethrestime(&now); 1183 1184 if (now_times & SMB_AT_ATIME) { 1185 attr->sa_vattr.va_atime = now; 1186 attr->sa_mask |= SMB_AT_ATIME; 1187 } 1188 if (now_times & SMB_AT_MTIME) { 1189 attr->sa_vattr.va_mtime = now; 1190 attr->sa_mask |= SMB_AT_MTIME; 1191 } 1192 if (now_times & SMB_AT_CTIME) { 1193 attr->sa_vattr.va_ctime = now; 1194 attr->sa_mask |= SMB_AT_CTIME; 1195 } 1196 } 1197 1198 if (attr->sa_mask == 0) 1199 return (0); 1200 1201 rc = smb_fsop_setattr(sr, cr, node, attr); 1202 if (rc != 0) 1203 return (rc); 1204 1205 smb_node_set_cached_timestamps(node, attr); 1206 1207 if (of) 1208 smb_ofile_set_explicit_times(of, (what & SMB_AT_TIMES)); 1209 1210 return (0); 1211 } 1212 1213 /* 1214 * smb_node_getattr 1215 * 1216 * Get attributes from the file system and apply any smb-specific 1217 * overrides for size, dos attributes and timestamps 1218 * 1219 * node->readonly_creator reflects whether a readonly set is pending 1220 * from a readonly create. The readonly attribute should be visible to 1221 * all clients even though the readonly creator fid is immune to the 1222 * readonly bit until close. 1223 * 1224 * Returns: errno 1225 */ 1226 int 1227 smb_node_getattr(smb_request_t *sr, smb_node_t *node, smb_attr_t *attr) 1228 { 1229 int rc; 1230 1231 SMB_NODE_VALID(node); 1232 1233 bzero(attr, sizeof (smb_attr_t)); 1234 attr->sa_mask = SMB_AT_ALL; 1235 rc = smb_fsop_getattr(sr, kcred, node, attr); 1236 if (rc != 0) 1237 return (rc); 1238 1239 mutex_enter(&node->n_mutex); 1240 1241 if (node->vp->v_type == VDIR) 1242 attr->sa_vattr.va_size = 0; 1243 1244 if (node->readonly_creator) 1245 attr->sa_dosattr |= FILE_ATTRIBUTE_READONLY; 1246 if (attr->sa_dosattr == 0) 1247 attr->sa_dosattr = FILE_ATTRIBUTE_NORMAL; 1248 1249 mutex_exit(&node->n_mutex); 1250 1251 smb_node_get_cached_timestamps(node, attr); 1252 return (0); 1253 } 1254 1255 /* 1256 * Timestamp caching 1257 * 1258 * Solaris file systems handle timestamps different from NTFS. For 1259 * example when file data is written NTFS doesn't update the timestamps 1260 * until the file is closed, and then only if they haven't been explicity 1261 * set via a set attribute request. In order to provide a more similar 1262 * view of an open file's timestamps, we cache the timestamps in the 1263 * node and manipulate them in a manner more consistent with windows. 1264 * (See handling of explicit times and pending timestamps from a write 1265 * request in smb_node_getattr and smb_node_setattr above.) 1266 * Timestamps remain cached while there are open ofiles for the node. 1267 * This includes open ofiles for named streams. 1268 * n_open_ofiles cannot be used as this doesn't include ofiles opened 1269 * for the node's named streams. Thus n_timestamps contains a count 1270 * of open ofiles (t_open_ofiles), including named streams' ofiles, 1271 * to be used to control timestamp caching. 1272 * 1273 * If a node represents a named stream the associated unnamed streams 1274 * cached timestamps are used instead. 1275 */ 1276 1277 /* 1278 * smb_node_init_cached_timestamps 1279 * 1280 * Increment count of open ofiles which are using the cached timestamps. 1281 * If this is the first open ofile, init the cached timestamps from the 1282 * file system values. 1283 */ 1284 static void 1285 smb_node_init_cached_timestamps(smb_node_t *node) 1286 { 1287 smb_node_t *unode; 1288 smb_attr_t attr; 1289 1290 if ((unode = SMB_IS_STREAM(node)) != NULL) 1291 node = unode; 1292 1293 mutex_enter(&node->n_mutex); 1294 ++(node->n_timestamps.t_open_ofiles); 1295 if (node->n_timestamps.t_open_ofiles == 1) { 1296 bzero(&attr, sizeof (smb_attr_t)); 1297 attr.sa_mask = SMB_AT_TIMES; 1298 (void) smb_fsop_getattr(NULL, kcred, node, &attr); 1299 node->n_timestamps.t_mtime = attr.sa_vattr.va_mtime; 1300 node->n_timestamps.t_atime = attr.sa_vattr.va_atime; 1301 node->n_timestamps.t_ctime = attr.sa_vattr.va_ctime; 1302 node->n_timestamps.t_crtime = attr.sa_crtime; 1303 node->n_timestamps.t_cached = B_TRUE; 1304 } 1305 mutex_exit(&node->n_mutex); 1306 } 1307 1308 /* 1309 * smb_node_clear_cached_timestamps 1310 * 1311 * Decrement count of open ofiles using the cached timestamps. 1312 * If the decremented count is zero, clear the cached timestamps. 1313 */ 1314 static void 1315 smb_node_clear_cached_timestamps(smb_node_t *node) 1316 { 1317 smb_node_t *unode; 1318 1319 if ((unode = SMB_IS_STREAM(node)) != NULL) 1320 node = unode; 1321 1322 mutex_enter(&node->n_mutex); 1323 ASSERT(node->n_timestamps.t_open_ofiles > 0); 1324 --(node->n_timestamps.t_open_ofiles); 1325 if (node->n_timestamps.t_open_ofiles == 0) 1326 bzero(&node->n_timestamps, sizeof (smb_times_t)); 1327 mutex_exit(&node->n_mutex); 1328 } 1329 1330 /* 1331 * smb_node_get_cached_timestamps 1332 * 1333 * Overwrite timestamps in attr with those cached in node. 1334 */ 1335 static void 1336 smb_node_get_cached_timestamps(smb_node_t *node, smb_attr_t *attr) 1337 { 1338 smb_node_t *unode; 1339 1340 if ((unode = SMB_IS_STREAM(node)) != NULL) 1341 node = unode; 1342 1343 mutex_enter(&node->n_mutex); 1344 if (node->n_timestamps.t_cached) { 1345 attr->sa_vattr.va_mtime = node->n_timestamps.t_mtime; 1346 attr->sa_vattr.va_atime = node->n_timestamps.t_atime; 1347 attr->sa_vattr.va_ctime = node->n_timestamps.t_ctime; 1348 attr->sa_crtime = node->n_timestamps.t_crtime; 1349 } 1350 mutex_exit(&node->n_mutex); 1351 } 1352 1353 /* 1354 * smb_node_set_cached_timestamps 1355 * 1356 * Update the node's cached timestamps with values from attr. 1357 */ 1358 static void 1359 smb_node_set_cached_timestamps(smb_node_t *node, smb_attr_t *attr) 1360 { 1361 smb_node_t *unode; 1362 1363 if ((unode = SMB_IS_STREAM(node)) != NULL) 1364 node = unode; 1365 1366 mutex_enter(&node->n_mutex); 1367 if (node->n_timestamps.t_cached) { 1368 if (attr->sa_mask & SMB_AT_MTIME) 1369 node->n_timestamps.t_mtime = attr->sa_vattr.va_mtime; 1370 if (attr->sa_mask & SMB_AT_ATIME) 1371 node->n_timestamps.t_atime = attr->sa_vattr.va_atime; 1372 if (attr->sa_mask & SMB_AT_CTIME) 1373 node->n_timestamps.t_ctime = attr->sa_vattr.va_ctime; 1374 if (attr->sa_mask & SMB_AT_CRTIME) 1375 node->n_timestamps.t_crtime = attr->sa_crtime; 1376 } 1377 mutex_exit(&node->n_mutex); 1378 } 1379