1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2021 Tintri by DDN, Inc. All rights reserved. 14 * Copyright 2021-2023 RackTop Systems, Inc. 15 */ 16 17 /* 18 * (SMB1/SMB2) Server-level Oplock support. 19 * 20 * Conceptually, this is a separate layer on top of the 21 * file system (FS) layer oplock code in smb_cmn_oplock.c. 22 * If these layers were more distinct, the FS layer would 23 * need to use call-back functions (installed from here) 24 * to "indicate an oplock break to the server" (see below). 25 * As these layers are all in the same kernel module, the 26 * delivery of these break indications just uses a direct 27 * function call to smb_oplock_ind_break() below. 28 * 29 * This layer is responsible for handling the break indication, 30 * which often requires scheduling a taskq job in the server, 31 * and sending an oplock break mesage to the client using 32 * the appropriate protocol for the open handle affected. 33 * 34 * The details of composing an oplock break message, the 35 * protocol-specific details of requesting an oplock, and 36 * returning that oplock to the client are in the files: 37 * smb_oplock.c, smb2_oplock.c, smb2_lease.c 38 */ 39 40 #include <smbsrv/smb2_kproto.h> 41 #include <smbsrv/smb_oplock.h> 42 43 /* 44 * Verify relationship between BREAK_TO_... and CACHE bits, 45 * used when setting the BREAK_TO_... below. 46 */ 47 #if BREAK_TO_READ_CACHING != (READ_CACHING << BREAK_SHIFT) 48 #error "BREAK_TO_READ_CACHING" 49 #endif 50 #if BREAK_TO_HANDLE_CACHING != (HANDLE_CACHING << BREAK_SHIFT) 51 #error "BREAK_TO_HANDLE_CACHING" 52 #endif 53 #if BREAK_TO_WRITE_CACHING != (WRITE_CACHING << BREAK_SHIFT) 54 #error "BREAK_TO_WRITE_CACHING" 55 #endif 56 #define CACHE_RWH (READ_CACHING | WRITE_CACHING | HANDLE_CACHING) 57 58 /* 59 * This is the timeout used in the thread that sends an 60 * oplock break and waits for the client to respond 61 * before it breaks the oplock locally. 62 */ 63 int smb_oplock_timeout_ack = 30000; /* mSec. */ 64 65 /* 66 * This is the timeout used in threads that have just 67 * finished some sort of oplock request and now must 68 * wait for (possibly multiple) breaks to complete. 69 * This value must be at least a couple seconds LONGER 70 * than the ack timeout above so that I/O callers won't 71 * give up waiting before the local ack timeout. 72 */ 73 int smb_oplock_timeout_def = 45000; /* mSec. */ 74 75 static void smb_oplock_async_break(void *); 76 static void smb_oplock_hdl_update(smb_request_t *sr); 77 static void smb_oplock_hdl_moved(smb_ofile_t *); 78 static void smb_oplock_hdl_closed(smb_ofile_t *); 79 static void smb_oplock_wait_break_cancel(smb_request_t *sr); 80 81 82 /* 83 * 2.1.5.17.3 Indicating an Oplock Break to the Server 84 * 85 * The inputs for indicating an oplock break to the server are: 86 * 87 * BreakingOplockOpen: The Open used to request the oplock 88 * that is now breaking. 89 * NewOplockLevel: The type of oplock the requested oplock 90 * has been broken to. Valid values are as follows: 91 * LEVEL_NONE (that is, no oplock) 92 * LEVEL_TWO 93 * A combination of one or more of the following flags: 94 * READ_CACHING 95 * HANDLE_CACHING 96 * WRITE_CACHING 97 * AcknowledgeRequired: A Boolean value; TRUE if the server 98 * MUST acknowledge the oplock break, FALSE if not, 99 * as specified in section 2.1.5.18. 100 * OplockCompletionStatus: The NTSTATUS code to return to the server. 101 * 102 * This algorithm simply represents the completion of an oplock request, 103 * as specified in section 2.1.5.17.1 or section 2.1.5.17.2. The server 104 * is expected to associate the return status from this algorithm with 105 * BreakingOplockOpen, which is the Open passed in when it requested 106 * the oplock that is now breaking. 107 * 108 * It is important to note that because several oplocks can be outstanding 109 * in parallel, although this algorithm represents the completion of an 110 * oplock request, it might not result in the completion of the algorithm 111 * that called it. In particular, calling this algorithm will result in 112 * completion of the caller only if BreakingOplockOpen is the same as the 113 * Open with which the calling algorithm was itself called. To mitigate 114 * confusion, each algorithm that refers to this section will specify 115 * whether that algorithm's operation terminates at that point or not. 116 * 117 * The object store MUST return OplockCompletionStatus, 118 * AcknowledgeRequired, and NewOplockLevel to the server (the algorithm is 119 * as specified in section 2.1.5.17.1 and section 2.1.5.17.2). 120 * 121 * Implementation: 122 * 123 * We use two versions of this function: 124 * smb_oplock_ind_break_in_ack 125 * smb_oplock_ind_break 126 * 127 * The first is used when we're handling an Oplock Break Ack. 128 * The second is used when other operations cause a break, 129 * generally in one of the smb_oplock_break_... functions. 130 * 131 * Note that these are call-back functions that may be called with the 132 * node ofile list rwlock held and the node oplock mutex entered, so 133 * these should ONLY schedule oplock break work, and MUST NOT attempt 134 * any actions that might require either of those locks. 135 */ 136 137 /* 138 * smb_oplock_ind_break_in_ack 139 * 140 * Variant of smb_oplock_ind_break() for the oplock Ack handler. 141 * When we need to indicate another oplock break from within the 142 * Ack handler (during the Ack. of some previous oplock break) 143 * we need to make sure this new break indication goes out only 144 * AFTER the reply to the current break ack. is sent out. 145 * 146 * In this case, we always have an SR (the break ack) so we can 147 * append the "ind break" work to the current SR and let the 148 * request hander thread do this work after the reply is sent. 149 * Note: this is always an SMB2 or later request, because this 150 * only happens for "granular" oplocks, which are SMB2-only. 151 * 152 * This is mostly the same as smb_oplock_ind_break() except: 153 * - The only CompletionStatus possible is STATUS_CANT_GRANT. 154 * - Instead of taskq_dispatch this appends the new SR to 155 * the "post work" queue on the current SR (if possible). 156 * 157 * Note called with the node ofile list rwlock held and 158 * the oplock mutex entered. 159 */ 160 void 161 smb_oplock_ind_break_in_ack(smb_request_t *ack_sr, smb_ofile_t *ofile, 162 uint32_t NewLevel, boolean_t AckRequired) 163 { 164 smb_server_t *sv = ofile->f_server; 165 smb_node_t *node = ofile->f_node; 166 smb_request_t *sr = NULL; 167 taskqid_t tqid; 168 boolean_t use_postwork = B_TRUE; 169 170 ASSERT(RW_READ_HELD(&node->n_ofile_list.ll_lock)); 171 ASSERT(MUTEX_HELD(&node->n_oplock.ol_mutex)); 172 173 /* 174 * This should happen only with SMB2 or later, 175 * but in case that ever changes... 176 */ 177 if (ack_sr->session->dialect < SMB_VERS_2_BASE) { 178 smb_oplock_ind_break(ofile, NewLevel, 179 AckRequired, STATUS_CANT_GRANT); 180 return; 181 } 182 183 /* 184 * We're going to schedule a request that will have a 185 * reference to this ofile. Get the hold first. 186 */ 187 if (!smb_ofile_hold_olbrk(ofile)) { 188 /* It's closing (or whatever). Nothing to do. */ 189 return; 190 } 191 192 /* 193 * When called from Ack processing, we want to use a 194 * request on the session doing the ack, so we can 195 * append "post work" to that session. If we can't 196 * allocate a request on that session (because it's 197 * now disconnecting) use a request from the server 198 * session like smb_oplock_ind_break does, and then 199 * use taskq_dispatch instead of postwork. 200 */ 201 sr = smb_request_alloc(ack_sr->session, 0); 202 if (sr == NULL) { 203 use_postwork = B_FALSE; 204 sr = smb_request_alloc(sv->sv_session, 0); 205 } 206 if (sr == NULL) { 207 /* 208 * Server must be shutting down. We took a 209 * hold on the ofile that must be released, 210 * but we can't release here because we're 211 * called with the node ofile list entered. 212 * See smb_ofile_release_LL. 213 */ 214 smb_llist_post(&node->n_ofile_list, ofile, 215 smb_ofile_release_LL); 216 return; 217 } 218 219 sr->sr_state = SMB_REQ_STATE_SUBMITTED; 220 sr->smb2_async = B_TRUE; 221 sr->user_cr = zone_kcred(); 222 sr->fid_ofile = ofile; 223 if (ofile->f_tree != NULL) { 224 sr->tid_tree = ofile->f_tree; 225 smb_tree_hold_internal(sr->tid_tree); 226 } 227 if (ofile->f_user != NULL) { 228 sr->uid_user = ofile->f_user; 229 smb_user_hold_internal(sr->uid_user); 230 } 231 if (ofile->f_lease != NULL) 232 NewLevel |= OPLOCK_LEVEL_GRANULAR; 233 234 sr->arg.olbrk.NewLevel = NewLevel; 235 sr->arg.olbrk.AckRequired = AckRequired; 236 237 /* 238 * Could do this in _hdl_update but this way it's 239 * visible in the dtrace fbt entry probe. 240 */ 241 sr->arg.olbrk.OldLevel = ofile->f_oplock.og_breakto; 242 243 smb_oplock_hdl_update(sr); 244 245 if (use_postwork) { 246 /* 247 * Using smb2_cmd_code to indicate what to call. 248 * work func. will call smb_oplock_send_brk 249 */ 250 sr->smb2_cmd_code = SMB2_OPLOCK_BREAK; 251 smb2sr_append_postwork(ack_sr, sr); 252 return; 253 } 254 255 /* Will call smb_oplock_send_break */ 256 sr->smb2_status = STATUS_CANT_GRANT; 257 tqid = taskq_dispatch(sv->sv_notify_pool, 258 smb_oplock_async_break, sr, TQ_SLEEP); 259 VERIFY(tqid != TASKQID_INVALID); 260 } 261 262 /* 263 * smb_oplock_ind_break 264 * 265 * This is the function described in [MS-FSA] 2.1.5.17.3 266 * which is called many places in the oplock break code. 267 * 268 * Schedule a request & taskq job to do oplock break work 269 * as requested by the FS-level code (smb_cmn_oplock.c). 270 * 271 * See also: smb_oplock_ind_break_in_ack 272 * 273 * Note called with the node ofile list rwlock held and 274 * the oplock mutex entered. 275 */ 276 void 277 smb_oplock_ind_break(smb_ofile_t *ofile, uint32_t NewLevel, 278 boolean_t AckRequired, uint32_t CompletionStatus) 279 { 280 smb_server_t *sv = ofile->f_server; 281 smb_node_t *node = ofile->f_node; 282 smb_request_t *sr = NULL; 283 taskqid_t tqid; 284 285 ASSERT(RW_READ_HELD(&node->n_ofile_list.ll_lock)); 286 ASSERT(MUTEX_HELD(&node->n_oplock.ol_mutex)); 287 288 /* 289 * See notes at smb_oplock_async_break re. CompletionStatus 290 * Check for any invalid codes here, so assert happens in 291 * the thread passing an unexpected value. 292 * The real work happens in a taskq job. 293 */ 294 switch (CompletionStatus) { 295 296 case NT_STATUS_SUCCESS: 297 case STATUS_CANT_GRANT: 298 /* Send break via taskq job. */ 299 break; 300 301 case STATUS_NEW_HANDLE: 302 smb_oplock_hdl_moved(ofile); 303 return; 304 305 case NT_STATUS_OPLOCK_HANDLE_CLOSED: 306 smb_oplock_hdl_closed(ofile); 307 return; 308 309 default: 310 ASSERT(0); 311 return; 312 } 313 314 /* 315 * We're going to schedule a request that will have a 316 * reference to this ofile. Get the hold first. 317 */ 318 if (!smb_ofile_hold_olbrk(ofile)) { 319 /* It's closing (or whatever). Nothing to do. */ 320 return; 321 } 322 323 /* 324 * We need a request allocated on the session that owns 325 * this ofile in order to safely send on that session. 326 * 327 * Note that while we hold a ref. on the ofile, it's 328 * f_session will not change. An ofile in state 329 * _ORPHANED will have f_session == NULL, but the 330 * f_session won't _change_ while we have a ref, 331 * and won't be torn down under our feet. 332 * Same for f_tree and f_user 333 * 334 * If f_session is NULL, or it's in a state that doesn't 335 * allow new requests, use the special "server" session. 336 */ 337 if (ofile->f_session != NULL) 338 sr = smb_request_alloc(ofile->f_session, 0); 339 if (sr == NULL) 340 sr = smb_request_alloc(sv->sv_session, 0); 341 if (sr == NULL) { 342 /* 343 * Server must be shutting down. We took a 344 * hold on the ofile that must be released, 345 * but we can't release here because we're 346 * called with the node ofile list entered. 347 * See smb_ofile_release_LL. 348 */ 349 smb_llist_post(&node->n_ofile_list, ofile, 350 smb_ofile_release_LL); 351 return; 352 } 353 354 sr->sr_state = SMB_REQ_STATE_SUBMITTED; 355 sr->smb2_async = B_TRUE; 356 sr->user_cr = zone_kcred(); 357 sr->fid_ofile = ofile; 358 if (ofile->f_tree != NULL) { 359 sr->tid_tree = ofile->f_tree; 360 smb_tree_hold_internal(sr->tid_tree); 361 } 362 if (ofile->f_user != NULL) { 363 sr->uid_user = ofile->f_user; 364 smb_user_hold_internal(sr->uid_user); 365 } 366 if (ofile->f_lease != NULL) 367 NewLevel |= OPLOCK_LEVEL_GRANULAR; 368 369 sr->arg.olbrk.NewLevel = NewLevel; 370 sr->arg.olbrk.AckRequired = AckRequired; 371 sr->smb2_status = CompletionStatus; 372 373 /* 374 * Could do this in _hdl_update but this way it's 375 * visible in the dtrace fbt entry probe. 376 */ 377 sr->arg.olbrk.OldLevel = ofile->f_oplock.og_breakto; 378 379 smb_oplock_hdl_update(sr); 380 381 /* Will call smb_oplock_send_break */ 382 tqid = taskq_dispatch(sv->sv_notify_pool, 383 smb_oplock_async_break, sr, TQ_SLEEP); 384 VERIFY(tqid != TASKQID_INVALID); 385 } 386 387 /* 388 * smb_oplock_async_break 389 * 390 * Called via the taskq to handle an asynchronous oplock break. 391 * We have a hold on the ofile, which will be released in 392 * smb_request_free (via sr->fid_ofile) 393 * 394 * Note we may have: sr->uid_user == NULL, sr->tid_tree == NULL. 395 */ 396 static void 397 smb_oplock_async_break(void *arg) 398 { 399 smb_request_t *sr = arg; 400 uint32_t CompletionStatus; 401 402 SMB_REQ_VALID(sr); 403 404 CompletionStatus = sr->smb2_status; 405 sr->smb2_status = NT_STATUS_SUCCESS; 406 407 mutex_enter(&sr->sr_mutex); 408 sr->sr_worker = curthread; 409 sr->sr_state = SMB_REQ_STATE_ACTIVE; 410 mutex_exit(&sr->sr_mutex); 411 412 /* 413 * Note that the CompletionStatus from the FS level 414 * (smb_cmn_oplock.c) encodes what kind of action we 415 * need to take at the SMB level. 416 */ 417 switch (CompletionStatus) { 418 419 case STATUS_CANT_GRANT: 420 case NT_STATUS_SUCCESS: 421 smb_oplock_send_break(sr); 422 break; 423 424 default: 425 /* Checked by caller. */ 426 ASSERT(0); 427 break; 428 } 429 430 if (sr->dh_nvl_dirty) { 431 sr->dh_nvl_dirty = B_FALSE; 432 smb2_dh_update_nvfile(sr); 433 } 434 435 sr->sr_state = SMB_REQ_STATE_COMPLETED; 436 smb_request_free(sr); 437 } 438 439 /* 440 * Send an oplock (or lease) break to the client. 441 * If we can't, then do a local break. 442 * 443 * This is called either from smb_oplock_async_break via a 444 * taskq job scheduled in smb_oplock_ind_break, or from the 445 * smb2sr_append_postwork() mechanism when we're doing a 446 * "break in ack", via smb_oplock_ind_break_in_ack. 447 * 448 * We don't always have an sr->session here, so 449 * determine the oplock type (lease etc) from 450 * f_lease and f_oplock.og_dialect etc. 451 */ 452 void 453 smb_oplock_send_break(smb_request_t *sr) 454 { 455 smb_ofile_t *ofile = sr->fid_ofile; 456 457 if (ofile->f_lease != NULL) 458 smb2_lease_send_break(sr); 459 else if (ofile->f_oplock.og_dialect >= SMB_VERS_2_BASE) 460 smb2_oplock_send_break(sr); 461 else 462 smb1_oplock_send_break(sr); 463 } 464 465 /* 466 * Called by smb_oplock_ind_break for the case STATUS_NEW_HANDLE, 467 * which is an alias for NT_STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE. 468 * 469 * The FS-level oplock layer calls this to update the SMB-level state 470 * when the oplock for some lease is about to move to a different 471 * ofile on the lease. 472 * 473 * To avoid later confusion, clear og_state on this ofile now. 474 * Without this, smb_oplock_move() may issue debug complaints 475 * about moving oplock state onto a non-empty oplock. 476 */ 477 static const smb_ofile_t invalid_ofile; 478 static void 479 smb_oplock_hdl_moved(smb_ofile_t *ofile) 480 { 481 smb_lease_t *ls = ofile->f_lease; 482 483 ASSERT(ls != NULL); 484 if (ls != NULL && ls->ls_oplock_ofile == ofile) 485 ls->ls_oplock_ofile = (smb_ofile_t *)&invalid_ofile; 486 487 ofile->f_oplock.og_state = 0; 488 ofile->f_oplock.og_breakto = 0; 489 ofile->f_oplock.og_breaking = B_FALSE; 490 } 491 492 /* 493 * See: NT_STATUS_OPLOCK_HANDLE_CLOSED above and 494 * smb_ofile_close, smb_oplock_break_CLOSE. 495 * 496 * The FS-level oplock layer calls this to update the 497 * SMB-level state when a handle loses its oplock. 498 */ 499 static void 500 smb_oplock_hdl_closed(smb_ofile_t *ofile) 501 { 502 smb_lease_t *lease = ofile->f_lease; 503 504 if (lease != NULL) { 505 if (lease->ls_oplock_ofile == ofile) { 506 /* 507 * smb2_lease_ofile_close should have 508 * moved the oplock to another ofile. 509 */ 510 ASSERT(0); 511 lease->ls_oplock_ofile = NULL; 512 } 513 } 514 ofile->f_oplock.og_state = 0; 515 ofile->f_oplock.og_breakto = 0; 516 ofile->f_oplock.og_breaking = B_FALSE; 517 } 518 519 /* 520 * smb_oplock_hdl_update 521 * 522 * Called by smb_oplock_ind_break (and ...in_ack) just before we 523 * schedule smb_oplock_async_break / mb_oplock_send_break taskq job, 524 * so we can make any state changes that should happen immediately. 525 * 526 * Here, keep track of what we will send to the client. 527 * Saves old state in arg.olbck.OldLevel 528 * 529 * Note that because we may be in the midst of processing an 530 * smb_oplock_ack_break call here, the _breaking flag will be 531 * temporarily false, and is set true again if this ack causes 532 * another break. This makes it tricky to know when to update 533 * the epoch, which is not supposed to increment when there's 534 * already an unacknowledged break out to the client. 535 * We can recognize that by comparing ls_state vs ls_breakto. 536 * If no unacknowledged break, ls_state == ls_breakto. 537 */ 538 static void 539 smb_oplock_hdl_update(smb_request_t *sr) 540 { 541 smb_ofile_t *ofile = sr->fid_ofile; 542 smb_lease_t *lease = ofile->f_lease; 543 uint32_t NewLevel = sr->arg.olbrk.NewLevel; 544 boolean_t AckReq = sr->arg.olbrk.AckRequired; 545 546 #ifdef DEBUG 547 smb_node_t *node = ofile->f_node; 548 ASSERT(RW_READ_HELD(&node->n_ofile_list.ll_lock)); 549 ASSERT(MUTEX_HELD(&node->n_oplock.ol_mutex)); 550 #endif 551 552 /* Caller sets arg.olbrk.OldLevel */ 553 ofile->f_oplock.og_breakto = NewLevel; 554 ofile->f_oplock.og_breaking = B_TRUE; 555 if (lease != NULL) { 556 // If no unacknowledged break, update epoch. 557 if (lease->ls_breakto == lease->ls_state) 558 lease->ls_epoch++; 559 560 lease->ls_breakto = NewLevel; 561 lease->ls_breaking = B_TRUE; 562 } 563 564 if (!AckReq) { 565 /* 566 * Not expecting an Ack from the client. 567 * Update state immediately. 568 */ 569 ofile->f_oplock.og_state = NewLevel; 570 ofile->f_oplock.og_breaking = B_FALSE; 571 if (lease != NULL) { 572 lease->ls_state = NewLevel; 573 lease->ls_breaking = B_FALSE; 574 } 575 if (ofile->dh_persist) { 576 smb2_dh_update_oplock(sr, ofile); 577 } 578 } 579 } 580 581 /* 582 * Helper for smb_ofile_close 583 * 584 * Note that a client may close an ofile in response to an 585 * oplock break or lease break intead of doing an Ack break, 586 * so this must wake anything that might be waiting on an ack. 587 */ 588 void 589 smb_oplock_close(smb_ofile_t *ofile) 590 { 591 smb_node_t *node = ofile->f_node; 592 593 smb_llist_enter(&node->n_ofile_list, RW_READER); 594 mutex_enter(&node->n_oplock.ol_mutex); 595 596 if (ofile->f_oplock_closing == B_FALSE) { 597 ofile->f_oplock_closing = B_TRUE; 598 599 if (ofile->f_lease != NULL) 600 smb2_lease_ofile_close(ofile); 601 602 smb_oplock_break_CLOSE(node, ofile); 603 604 ofile->f_oplock.og_state = 0; 605 ofile->f_oplock.og_breakto = 0; 606 ofile->f_oplock.og_breaking = B_FALSE; 607 cv_broadcast(&ofile->f_oplock.og_ack_cv); 608 } 609 610 mutex_exit(&node->n_oplock.ol_mutex); 611 smb_llist_exit(&node->n_ofile_list); 612 } 613 614 /* 615 * Called by smb_request_cancel() via sr->cancel_method 616 * Arg is the smb_node_t with the breaking oplock. 617 */ 618 static void 619 smb_oplock_wait_ack_cancel(smb_request_t *sr) 620 { 621 kcondvar_t *cvp = sr->cancel_arg2; 622 smb_ofile_t *ofile = sr->fid_ofile; 623 smb_node_t *node = ofile->f_node; 624 625 mutex_enter(&node->n_oplock.ol_mutex); 626 cv_broadcast(cvp); 627 mutex_exit(&node->n_oplock.ol_mutex); 628 } 629 630 /* 631 * Wait for an oplock break ACK to arrive. This is called after 632 * we've sent an oplock break or lease break to the client where 633 * an "Ack break" is expected back. If we get an Ack, that will 634 * wake us up via smb2_oplock_break_ack or smb2_lease_break_ack. 635 * 636 * Wait until state reduced to NewLevel (or less). 637 * Note that in multi-break cases, we might wait here for just 638 * one ack when another has become pending, in which case the 639 * og_breakto might be a subset of NewLevel. Wait until the 640 * state field is no longer a superset of NewLevel. 641 */ 642 uint32_t 643 smb_oplock_wait_ack(smb_request_t *sr, uint32_t NewLevel) 644 { 645 smb_ofile_t *ofile = sr->fid_ofile; 646 smb_lease_t *lease = ofile->f_lease; 647 smb_node_t *node = ofile->f_node; 648 smb_oplock_t *ol = &node->n_oplock; 649 uint32_t *state_p; 650 kcondvar_t *cv_p; 651 clock_t time, rv; 652 uint32_t status = 0; 653 smb_req_state_t srstate; 654 uint32_t wait_mask; 655 656 time = ddi_get_lbolt() + 657 MSEC_TO_TICK(smb_oplock_timeout_ack); 658 659 /* 660 * Wait on either lease state or oplock state 661 */ 662 if (lease != NULL) { 663 state_p = &lease->ls_state; 664 cv_p = &lease->ls_ack_cv; 665 } else { 666 state_p = &ofile->f_oplock.og_state; 667 cv_p = &ofile->f_oplock.og_ack_cv; 668 } 669 670 /* 671 * These are all the bits that we wait to be cleared. 672 */ 673 wait_mask = ~NewLevel & (CACHE_RWH | 674 LEVEL_TWO | LEVEL_ONE | LEVEL_BATCH); 675 676 /* 677 * Setup cancellation callback 678 */ 679 mutex_enter(&sr->sr_mutex); 680 if (sr->sr_state != SMB_REQ_STATE_ACTIVE) { 681 mutex_exit(&sr->sr_mutex); 682 return (NT_STATUS_CANCELLED); 683 } 684 sr->sr_state = SMB_REQ_STATE_WAITING_OLBRK; 685 sr->cancel_method = smb_oplock_wait_ack_cancel; 686 sr->cancel_arg2 = cv_p; 687 mutex_exit(&sr->sr_mutex); 688 689 /* 690 * Enter the wait loop 691 */ 692 mutex_enter(&ol->ol_mutex); 693 694 while ((*state_p & wait_mask) != 0) { 695 rv = cv_timedwait(cv_p, &ol->ol_mutex, time); 696 if (rv < 0) { 697 /* cv_timewait timeout */ 698 char *fname; 699 char *opname; 700 int rc; 701 702 /* 703 * Get the path name of the open file 704 */ 705 fname = smb_srm_zalloc(sr, MAXPATHLEN); 706 rc = smb_node_getpath(node, NULL, fname, MAXPATHLEN); 707 if (rc != 0) { 708 /* Not expected. Just show last part. */ 709 (void) snprintf(fname, MAXPATHLEN, "(?)/%s", 710 node->od_name); 711 } 712 713 /* 714 * Get an operation name reflecting which kind of 715 * lease or oplock break got us here, so the log 716 * message will say "lease break" or whatever. 717 */ 718 if (lease != NULL) { 719 opname = "lease"; 720 } else if (ofile->f_oplock.og_dialect >= 721 SMB_VERS_2_BASE) { 722 opname = "oplock2"; 723 } else { 724 opname = "oplock1"; 725 } 726 727 cmn_err(CE_NOTE, "!client %s %s break timeout for %s", 728 sr->session->ip_addr_str, opname, fname); 729 730 status = NT_STATUS_CANNOT_BREAK_OPLOCK; 731 break; 732 } 733 734 /* 735 * Check if we were woken by smb_request_cancel, 736 * which sets state SMB_REQ_STATE_CANCEL_PENDING 737 * and signals the CV. The mutex enter/exit is 738 * just to ensure cache visibility of sr_state 739 * that was updated in smb_request_cancel. 740 */ 741 mutex_enter(&sr->sr_mutex); 742 srstate = sr->sr_state; 743 mutex_exit(&sr->sr_mutex); 744 if (srstate != SMB_REQ_STATE_WAITING_OLBRK) { 745 break; 746 } 747 } 748 mutex_exit(&ol->ol_mutex); 749 750 /* 751 * See if it completed or if it was cancelled. 752 */ 753 mutex_enter(&sr->sr_mutex); 754 switch_state: 755 switch (sr->sr_state) { 756 case SMB_REQ_STATE_WAITING_OLBRK: 757 /* Normal wakeup. Keep status from above. */ 758 sr->sr_state = SMB_REQ_STATE_ACTIVE; 759 /* status from above */ 760 break; 761 case SMB_REQ_STATE_CANCEL_PENDING: 762 /* cancel_method running. wait. */ 763 cv_wait(&sr->sr_st_cv, &sr->sr_mutex); 764 goto switch_state; 765 case SMB_REQ_STATE_CANCELLED: 766 status = NT_STATUS_CANCELLED; 767 break; 768 default: 769 status = NT_STATUS_INTERNAL_ERROR; 770 break; 771 } 772 sr->cancel_method = NULL; 773 sr->cancel_arg2 = NULL; 774 mutex_exit(&sr->sr_mutex); 775 776 return (status); 777 } 778 779 /* 780 * Called by smb_request_cancel() via sr->cancel_method 781 * Arg is the smb_node_t with the breaking oplock. 782 */ 783 static void 784 smb_oplock_wait_break_cancel(smb_request_t *sr) 785 { 786 smb_node_t *node = sr->cancel_arg2; 787 smb_oplock_t *ol; 788 789 SMB_NODE_VALID(node); 790 ol = &node->n_oplock; 791 792 mutex_enter(&ol->ol_mutex); 793 cv_broadcast(&ol->WaitingOpenCV); 794 mutex_exit(&ol->ol_mutex); 795 } 796 797 /* 798 * Wait up to "timeout" mSec. for the current oplock "breaking" flags 799 * to be cleared (by smb_oplock_ack_break or smb_oplock_break_CLOSE). 800 * 801 * Callers of the above public oplock functions: 802 * smb_oplock_request() 803 * smb_oplock_ack_break() 804 * smb_oplock_break_OPEN() ... 805 * check for return status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS 806 * and call this function to wait for the break to complete. 807 * 808 * Most callers should use this default timeout, which they get 809 * by passing zero as the timeout arg. This include places where 810 * we're about to do something that invalidates some cache. 811 */ 812 uint32_t 813 smb_oplock_wait_break(smb_request_t *sr, smb_node_t *node, int timeout) 814 { 815 smb_oplock_t *ol; 816 clock_t time, rv; 817 uint32_t status = 0; 818 smb_req_state_t srstate; 819 820 SMB_NODE_VALID(node); 821 ol = &node->n_oplock; 822 823 if (timeout == 0) 824 timeout = smb_oplock_timeout_def; 825 time = MSEC_TO_TICK(timeout) + ddi_get_lbolt(); 826 827 /* 828 * Setup cancellation callback 829 */ 830 mutex_enter(&sr->sr_mutex); 831 if (sr->sr_state != SMB_REQ_STATE_ACTIVE) { 832 mutex_exit(&sr->sr_mutex); 833 return (NT_STATUS_CANCELLED); 834 } 835 sr->sr_state = SMB_REQ_STATE_WAITING_OLBRK; 836 sr->cancel_method = smb_oplock_wait_break_cancel; 837 sr->cancel_arg2 = node; 838 mutex_exit(&sr->sr_mutex); 839 840 mutex_enter(&ol->ol_mutex); 841 while ((ol->ol_state & BREAK_ANY) != 0) { 842 ol->waiters++; 843 rv = cv_timedwait(&ol->WaitingOpenCV, 844 &ol->ol_mutex, time); 845 ol->waiters--; 846 if (rv < 0) { 847 /* cv_timewait timeout */ 848 status = NT_STATUS_CANNOT_BREAK_OPLOCK; 849 break; 850 } 851 852 /* 853 * Check if we were woken by smb_request_cancel, 854 * which sets state SMB_REQ_STATE_CANCEL_PENDING 855 * and signals the CV. The mutex enter/exit is 856 * just to ensure cache visibility of sr_state 857 * that was updated in smb_request_cancel. 858 */ 859 mutex_enter(&sr->sr_mutex); 860 srstate = sr->sr_state; 861 mutex_exit(&sr->sr_mutex); 862 if (srstate != SMB_REQ_STATE_WAITING_OLBRK) { 863 break; 864 } 865 } 866 mutex_exit(&ol->ol_mutex); 867 868 /* 869 * Check whether it completed or was cancelled. 870 */ 871 mutex_enter(&sr->sr_mutex); 872 switch_state: 873 switch (sr->sr_state) { 874 case SMB_REQ_STATE_WAITING_OLBRK: 875 /* Normal wakeup. Keep status from above. */ 876 sr->sr_state = SMB_REQ_STATE_ACTIVE; 877 break; 878 case SMB_REQ_STATE_CANCEL_PENDING: 879 /* cancel_method running. wait. */ 880 cv_wait(&sr->sr_st_cv, &sr->sr_mutex); 881 goto switch_state; 882 case SMB_REQ_STATE_CANCELLED: 883 status = NT_STATUS_CANCELLED; 884 break; 885 default: 886 status = NT_STATUS_INTERNAL_ERROR; 887 break; 888 } 889 sr->cancel_method = NULL; 890 sr->cancel_arg2 = NULL; 891 mutex_exit(&sr->sr_mutex); 892 893 return (status); 894 } 895 896 /* 897 * Simplified version used in smb_fem.c, like above, 898 * but no smb_request_cancel stuff. 899 */ 900 uint32_t 901 smb_oplock_wait_break_fem(smb_node_t *node, int timeout) /* mSec. */ 902 { 903 smb_oplock_t *ol; 904 clock_t time, rv; 905 uint32_t status = 0; 906 907 if (timeout == 0) 908 timeout = smb_oplock_timeout_def; 909 910 SMB_NODE_VALID(node); 911 ol = &node->n_oplock; 912 913 mutex_enter(&ol->ol_mutex); 914 time = MSEC_TO_TICK(timeout) + ddi_get_lbolt(); 915 916 while ((ol->ol_state & BREAK_ANY) != 0) { 917 ol->waiters++; 918 rv = cv_timedwait(&ol->WaitingOpenCV, 919 &ol->ol_mutex, time); 920 ol->waiters--; 921 if (rv < 0) { 922 status = NT_STATUS_CANNOT_BREAK_OPLOCK; 923 break; 924 } 925 } 926 927 mutex_exit(&ol->ol_mutex); 928 929 return (status); 930 } 931