oplock.c (44997B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org> 4 * Copyright (C) 2018 Samsung Electronics Co., Ltd. 5 */ 6 7#include <linux/moduleparam.h> 8 9#include "glob.h" 10#include "oplock.h" 11 12#include "smb_common.h" 13#include "smbstatus.h" 14#include "connection.h" 15#include "mgmt/user_session.h" 16#include "mgmt/share_config.h" 17#include "mgmt/tree_connect.h" 18 19static LIST_HEAD(lease_table_list); 20static DEFINE_RWLOCK(lease_list_lock); 21 22/** 23 * alloc_opinfo() - allocate a new opinfo object for oplock info 24 * @work: smb work 25 * @id: fid of open file 26 * @Tid: tree id of connection 27 * 28 * Return: allocated opinfo object on success, otherwise NULL 29 */ 30static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, 31 u64 id, __u16 Tid) 32{ 33 struct ksmbd_session *sess = work->sess; 34 struct oplock_info *opinfo; 35 36 opinfo = kzalloc(sizeof(struct oplock_info), GFP_KERNEL); 37 if (!opinfo) 38 return NULL; 39 40 opinfo->sess = sess; 41 opinfo->conn = sess->conn; 42 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; 43 opinfo->op_state = OPLOCK_STATE_NONE; 44 opinfo->pending_break = 0; 45 opinfo->fid = id; 46 opinfo->Tid = Tid; 47 INIT_LIST_HEAD(&opinfo->op_entry); 48 INIT_LIST_HEAD(&opinfo->interim_list); 49 init_waitqueue_head(&opinfo->oplock_q); 50 init_waitqueue_head(&opinfo->oplock_brk); 51 atomic_set(&opinfo->refcount, 1); 52 atomic_set(&opinfo->breaking_cnt, 0); 53 54 return opinfo; 55} 56 57static void lease_add_list(struct oplock_info *opinfo) 58{ 59 struct lease_table *lb = opinfo->o_lease->l_lb; 60 61 spin_lock(&lb->lb_lock); 62 list_add_rcu(&opinfo->lease_entry, &lb->lease_list); 63 spin_unlock(&lb->lb_lock); 64} 65 66static void lease_del_list(struct oplock_info *opinfo) 67{ 68 struct lease_table *lb = opinfo->o_lease->l_lb; 69 70 if (!lb) 71 return; 72 73 spin_lock(&lb->lb_lock); 74 if (list_empty(&opinfo->lease_entry)) { 75 spin_unlock(&lb->lb_lock); 76 return; 77 } 78 79 list_del_init(&opinfo->lease_entry); 80 opinfo->o_lease->l_lb = NULL; 81 spin_unlock(&lb->lb_lock); 82} 83 84static void lb_add(struct lease_table *lb) 85{ 86 write_lock(&lease_list_lock); 87 list_add(&lb->l_entry, &lease_table_list); 88 write_unlock(&lease_list_lock); 89} 90 91static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) 92{ 93 struct lease *lease; 94 95 lease = kmalloc(sizeof(struct lease), GFP_KERNEL); 96 if (!lease) 97 return -ENOMEM; 98 99 memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE); 100 lease->state = lctx->req_state; 101 lease->new_state = 0; 102 lease->flags = lctx->flags; 103 lease->duration = lctx->duration; 104 memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE); 105 lease->version = lctx->version; 106 lease->epoch = 0; 107 INIT_LIST_HEAD(&opinfo->lease_entry); 108 opinfo->o_lease = lease; 109 110 return 0; 111} 112 113static void free_lease(struct oplock_info *opinfo) 114{ 115 struct lease *lease; 116 117 lease = opinfo->o_lease; 118 kfree(lease); 119} 120 121static void free_opinfo(struct oplock_info *opinfo) 122{ 123 if (opinfo->is_lease) 124 free_lease(opinfo); 125 kfree(opinfo); 126} 127 128static inline void opinfo_free_rcu(struct rcu_head *rcu_head) 129{ 130 struct oplock_info *opinfo; 131 132 opinfo = container_of(rcu_head, struct oplock_info, rcu_head); 133 free_opinfo(opinfo); 134} 135 136struct oplock_info *opinfo_get(struct ksmbd_file *fp) 137{ 138 struct oplock_info *opinfo; 139 140 rcu_read_lock(); 141 opinfo = rcu_dereference(fp->f_opinfo); 142 if (opinfo && !atomic_inc_not_zero(&opinfo->refcount)) 143 opinfo = NULL; 144 rcu_read_unlock(); 145 146 return opinfo; 147} 148 149static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci) 150{ 151 struct oplock_info *opinfo; 152 153 if (list_empty(&ci->m_op_list)) 154 return NULL; 155 156 rcu_read_lock(); 157 opinfo = list_first_or_null_rcu(&ci->m_op_list, struct oplock_info, 158 op_entry); 159 if (opinfo && !atomic_inc_not_zero(&opinfo->refcount)) 160 opinfo = NULL; 161 rcu_read_unlock(); 162 163 return opinfo; 164} 165 166void opinfo_put(struct oplock_info *opinfo) 167{ 168 if (!atomic_dec_and_test(&opinfo->refcount)) 169 return; 170 171 call_rcu(&opinfo->rcu_head, opinfo_free_rcu); 172} 173 174static void opinfo_add(struct oplock_info *opinfo) 175{ 176 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; 177 178 write_lock(&ci->m_lock); 179 list_add_rcu(&opinfo->op_entry, &ci->m_op_list); 180 write_unlock(&ci->m_lock); 181} 182 183static void opinfo_del(struct oplock_info *opinfo) 184{ 185 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; 186 187 if (opinfo->is_lease) { 188 write_lock(&lease_list_lock); 189 lease_del_list(opinfo); 190 write_unlock(&lease_list_lock); 191 } 192 write_lock(&ci->m_lock); 193 list_del_rcu(&opinfo->op_entry); 194 write_unlock(&ci->m_lock); 195} 196 197static unsigned long opinfo_count(struct ksmbd_file *fp) 198{ 199 if (ksmbd_stream_fd(fp)) 200 return atomic_read(&fp->f_ci->sop_count); 201 else 202 return atomic_read(&fp->f_ci->op_count); 203} 204 205static void opinfo_count_inc(struct ksmbd_file *fp) 206{ 207 if (ksmbd_stream_fd(fp)) 208 return atomic_inc(&fp->f_ci->sop_count); 209 else 210 return atomic_inc(&fp->f_ci->op_count); 211} 212 213static void opinfo_count_dec(struct ksmbd_file *fp) 214{ 215 if (ksmbd_stream_fd(fp)) 216 return atomic_dec(&fp->f_ci->sop_count); 217 else 218 return atomic_dec(&fp->f_ci->op_count); 219} 220 221/** 222 * opinfo_write_to_read() - convert a write oplock to read oplock 223 * @opinfo: current oplock info 224 * 225 * Return: 0 on success, otherwise -EINVAL 226 */ 227int opinfo_write_to_read(struct oplock_info *opinfo) 228{ 229 struct lease *lease = opinfo->o_lease; 230 231 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || 232 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { 233 pr_err("bad oplock(0x%x)\n", opinfo->level); 234 if (opinfo->is_lease) 235 pr_err("lease state(0x%x)\n", lease->state); 236 return -EINVAL; 237 } 238 opinfo->level = SMB2_OPLOCK_LEVEL_II; 239 240 if (opinfo->is_lease) 241 lease->state = lease->new_state; 242 return 0; 243} 244 245/** 246 * opinfo_read_handle_to_read() - convert a read/handle oplock to read oplock 247 * @opinfo: current oplock info 248 * 249 * Return: 0 on success, otherwise -EINVAL 250 */ 251int opinfo_read_handle_to_read(struct oplock_info *opinfo) 252{ 253 struct lease *lease = opinfo->o_lease; 254 255 lease->state = lease->new_state; 256 opinfo->level = SMB2_OPLOCK_LEVEL_II; 257 return 0; 258} 259 260/** 261 * opinfo_write_to_none() - convert a write oplock to none 262 * @opinfo: current oplock info 263 * 264 * Return: 0 on success, otherwise -EINVAL 265 */ 266int opinfo_write_to_none(struct oplock_info *opinfo) 267{ 268 struct lease *lease = opinfo->o_lease; 269 270 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || 271 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { 272 pr_err("bad oplock(0x%x)\n", opinfo->level); 273 if (opinfo->is_lease) 274 pr_err("lease state(0x%x)\n", lease->state); 275 return -EINVAL; 276 } 277 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; 278 if (opinfo->is_lease) 279 lease->state = lease->new_state; 280 return 0; 281} 282 283/** 284 * opinfo_read_to_none() - convert a write read to none 285 * @opinfo: current oplock info 286 * 287 * Return: 0 on success, otherwise -EINVAL 288 */ 289int opinfo_read_to_none(struct oplock_info *opinfo) 290{ 291 struct lease *lease = opinfo->o_lease; 292 293 if (opinfo->level != SMB2_OPLOCK_LEVEL_II) { 294 pr_err("bad oplock(0x%x)\n", opinfo->level); 295 if (opinfo->is_lease) 296 pr_err("lease state(0x%x)\n", lease->state); 297 return -EINVAL; 298 } 299 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; 300 if (opinfo->is_lease) 301 lease->state = lease->new_state; 302 return 0; 303} 304 305/** 306 * lease_read_to_write() - upgrade lease state from read to write 307 * @opinfo: current lease info 308 * 309 * Return: 0 on success, otherwise -EINVAL 310 */ 311int lease_read_to_write(struct oplock_info *opinfo) 312{ 313 struct lease *lease = opinfo->o_lease; 314 315 if (!(lease->state & SMB2_LEASE_READ_CACHING_LE)) { 316 ksmbd_debug(OPLOCK, "bad lease state(0x%x)\n", lease->state); 317 return -EINVAL; 318 } 319 320 lease->new_state = SMB2_LEASE_NONE_LE; 321 lease->state |= SMB2_LEASE_WRITE_CACHING_LE; 322 if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE) 323 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; 324 else 325 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; 326 return 0; 327} 328 329/** 330 * lease_none_upgrade() - upgrade lease state from none 331 * @opinfo: current lease info 332 * @new_state: new lease state 333 * 334 * Return: 0 on success, otherwise -EINVAL 335 */ 336static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state) 337{ 338 struct lease *lease = opinfo->o_lease; 339 340 if (!(lease->state == SMB2_LEASE_NONE_LE)) { 341 ksmbd_debug(OPLOCK, "bad lease state(0x%x)\n", lease->state); 342 return -EINVAL; 343 } 344 345 lease->new_state = SMB2_LEASE_NONE_LE; 346 lease->state = new_state; 347 if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE) 348 if (lease->state & SMB2_LEASE_WRITE_CACHING_LE) 349 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; 350 else 351 opinfo->level = SMB2_OPLOCK_LEVEL_II; 352 else if (lease->state & SMB2_LEASE_WRITE_CACHING_LE) 353 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; 354 else if (lease->state & SMB2_LEASE_READ_CACHING_LE) 355 opinfo->level = SMB2_OPLOCK_LEVEL_II; 356 357 return 0; 358} 359 360/** 361 * close_id_del_oplock() - release oplock object at file close time 362 * @fp: ksmbd file pointer 363 */ 364void close_id_del_oplock(struct ksmbd_file *fp) 365{ 366 struct oplock_info *opinfo; 367 368 if (S_ISDIR(file_inode(fp->filp)->i_mode)) 369 return; 370 371 opinfo = opinfo_get(fp); 372 if (!opinfo) 373 return; 374 375 opinfo_del(opinfo); 376 377 rcu_assign_pointer(fp->f_opinfo, NULL); 378 if (opinfo->op_state == OPLOCK_ACK_WAIT) { 379 opinfo->op_state = OPLOCK_CLOSING; 380 wake_up_interruptible_all(&opinfo->oplock_q); 381 if (opinfo->is_lease) { 382 atomic_set(&opinfo->breaking_cnt, 0); 383 wake_up_interruptible_all(&opinfo->oplock_brk); 384 } 385 } 386 387 opinfo_count_dec(fp); 388 atomic_dec(&opinfo->refcount); 389 opinfo_put(opinfo); 390} 391 392/** 393 * grant_write_oplock() - grant exclusive/batch oplock or write lease 394 * @opinfo_new: new oplock info object 395 * @req_oplock: request oplock 396 * @lctx: lease context information 397 * 398 * Return: 0 399 */ 400static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock, 401 struct lease_ctx_info *lctx) 402{ 403 struct lease *lease = opinfo_new->o_lease; 404 405 if (req_oplock == SMB2_OPLOCK_LEVEL_BATCH) 406 opinfo_new->level = SMB2_OPLOCK_LEVEL_BATCH; 407 else 408 opinfo_new->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; 409 410 if (lctx) { 411 lease->state = lctx->req_state; 412 memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE); 413 } 414} 415 416/** 417 * grant_read_oplock() - grant level2 oplock or read lease 418 * @opinfo_new: new oplock info object 419 * @lctx: lease context information 420 * 421 * Return: 0 422 */ 423static void grant_read_oplock(struct oplock_info *opinfo_new, 424 struct lease_ctx_info *lctx) 425{ 426 struct lease *lease = opinfo_new->o_lease; 427 428 opinfo_new->level = SMB2_OPLOCK_LEVEL_II; 429 430 if (lctx) { 431 lease->state = SMB2_LEASE_READ_CACHING_LE; 432 if (lctx->req_state & SMB2_LEASE_HANDLE_CACHING_LE) 433 lease->state |= SMB2_LEASE_HANDLE_CACHING_LE; 434 memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE); 435 } 436} 437 438/** 439 * grant_none_oplock() - grant none oplock or none lease 440 * @opinfo_new: new oplock info object 441 * @lctx: lease context information 442 * 443 * Return: 0 444 */ 445static void grant_none_oplock(struct oplock_info *opinfo_new, 446 struct lease_ctx_info *lctx) 447{ 448 struct lease *lease = opinfo_new->o_lease; 449 450 opinfo_new->level = SMB2_OPLOCK_LEVEL_NONE; 451 452 if (lctx) { 453 lease->state = 0; 454 memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE); 455 } 456} 457 458static inline int compare_guid_key(struct oplock_info *opinfo, 459 const char *guid1, const char *key1) 460{ 461 const char *guid2, *key2; 462 463 guid2 = opinfo->conn->ClientGUID; 464 key2 = opinfo->o_lease->lease_key; 465 if (!memcmp(guid1, guid2, SMB2_CLIENT_GUID_SIZE) && 466 !memcmp(key1, key2, SMB2_LEASE_KEY_SIZE)) 467 return 1; 468 469 return 0; 470} 471 472/** 473 * same_client_has_lease() - check whether current lease request is 474 * from lease owner of file 475 * @ci: master file pointer 476 * @client_guid: Client GUID 477 * @lctx: lease context information 478 * 479 * Return: oplock(lease) object on success, otherwise NULL 480 */ 481static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, 482 char *client_guid, 483 struct lease_ctx_info *lctx) 484{ 485 int ret; 486 struct lease *lease; 487 struct oplock_info *opinfo; 488 struct oplock_info *m_opinfo = NULL; 489 490 if (!lctx) 491 return NULL; 492 493 /* 494 * Compare lease key and client_guid to know request from same owner 495 * of same client 496 */ 497 read_lock(&ci->m_lock); 498 list_for_each_entry(opinfo, &ci->m_op_list, op_entry) { 499 if (!opinfo->is_lease) 500 continue; 501 read_unlock(&ci->m_lock); 502 lease = opinfo->o_lease; 503 504 ret = compare_guid_key(opinfo, client_guid, lctx->lease_key); 505 if (ret) { 506 m_opinfo = opinfo; 507 /* skip upgrading lease about breaking lease */ 508 if (atomic_read(&opinfo->breaking_cnt)) { 509 read_lock(&ci->m_lock); 510 continue; 511 } 512 513 /* upgrading lease */ 514 if ((atomic_read(&ci->op_count) + 515 atomic_read(&ci->sop_count)) == 1) { 516 if (lease->state == 517 (lctx->req_state & lease->state)) { 518 lease->state |= lctx->req_state; 519 if (lctx->req_state & 520 SMB2_LEASE_WRITE_CACHING_LE) 521 lease_read_to_write(opinfo); 522 } 523 } else if ((atomic_read(&ci->op_count) + 524 atomic_read(&ci->sop_count)) > 1) { 525 if (lctx->req_state == 526 (SMB2_LEASE_READ_CACHING_LE | 527 SMB2_LEASE_HANDLE_CACHING_LE)) 528 lease->state = lctx->req_state; 529 } 530 531 if (lctx->req_state && lease->state == 532 SMB2_LEASE_NONE_LE) 533 lease_none_upgrade(opinfo, lctx->req_state); 534 } 535 read_lock(&ci->m_lock); 536 } 537 read_unlock(&ci->m_lock); 538 539 return m_opinfo; 540} 541 542static void wait_for_break_ack(struct oplock_info *opinfo) 543{ 544 int rc = 0; 545 546 rc = wait_event_interruptible_timeout(opinfo->oplock_q, 547 opinfo->op_state == OPLOCK_STATE_NONE || 548 opinfo->op_state == OPLOCK_CLOSING, 549 OPLOCK_WAIT_TIME); 550 551 /* is this a timeout ? */ 552 if (!rc) { 553 if (opinfo->is_lease) 554 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; 555 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; 556 opinfo->op_state = OPLOCK_STATE_NONE; 557 } 558} 559 560static void wake_up_oplock_break(struct oplock_info *opinfo) 561{ 562 clear_bit_unlock(0, &opinfo->pending_break); 563 /* memory barrier is needed for wake_up_bit() */ 564 smp_mb__after_atomic(); 565 wake_up_bit(&opinfo->pending_break, 0); 566} 567 568static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level) 569{ 570 while (test_and_set_bit(0, &opinfo->pending_break)) { 571 wait_on_bit(&opinfo->pending_break, 0, TASK_UNINTERRUPTIBLE); 572 573 /* Not immediately break to none. */ 574 opinfo->open_trunc = 0; 575 576 if (opinfo->op_state == OPLOCK_CLOSING) 577 return -ENOENT; 578 else if (!opinfo->is_lease && opinfo->level <= req_op_level) 579 return 1; 580 } 581 582 if (!opinfo->is_lease && opinfo->level <= req_op_level) { 583 wake_up_oplock_break(opinfo); 584 return 1; 585 } 586 return 0; 587} 588 589static inline int allocate_oplock_break_buf(struct ksmbd_work *work) 590{ 591 work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL); 592 if (!work->response_buf) 593 return -ENOMEM; 594 work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; 595 return 0; 596} 597 598/** 599 * __smb2_oplock_break_noti() - send smb2 oplock break cmd from conn 600 * to client 601 * @wk: smb work object 602 * 603 * There are two ways this function can be called. 1- while file open we break 604 * from exclusive/batch lock to levelII oplock and 2- while file write/truncate 605 * we break from levelII oplock no oplock. 606 * work->request_buf contains oplock_info. 607 */ 608static void __smb2_oplock_break_noti(struct work_struct *wk) 609{ 610 struct smb2_oplock_break *rsp = NULL; 611 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); 612 struct ksmbd_conn *conn = work->conn; 613 struct oplock_break_info *br_info = work->request_buf; 614 struct smb2_hdr *rsp_hdr; 615 struct ksmbd_file *fp; 616 617 fp = ksmbd_lookup_durable_fd(br_info->fid); 618 if (!fp) { 619 atomic_dec(&conn->r_count); 620 ksmbd_free_work_struct(work); 621 return; 622 } 623 624 if (allocate_oplock_break_buf(work)) { 625 pr_err("smb2_allocate_rsp_buf failed! "); 626 atomic_dec(&conn->r_count); 627 ksmbd_fd_put(work, fp); 628 ksmbd_free_work_struct(work); 629 return; 630 } 631 632 rsp_hdr = smb2_get_msg(work->response_buf); 633 memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); 634 *(__be32 *)work->response_buf = 635 cpu_to_be32(conn->vals->header_size); 636 rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; 637 rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; 638 rsp_hdr->CreditRequest = cpu_to_le16(0); 639 rsp_hdr->Command = SMB2_OPLOCK_BREAK; 640 rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR); 641 rsp_hdr->NextCommand = 0; 642 rsp_hdr->MessageId = cpu_to_le64(-1); 643 rsp_hdr->Id.SyncId.ProcessId = 0; 644 rsp_hdr->Id.SyncId.TreeId = 0; 645 rsp_hdr->SessionId = 0; 646 memset(rsp_hdr->Signature, 0, 16); 647 648 rsp = smb2_get_msg(work->response_buf); 649 650 rsp->StructureSize = cpu_to_le16(24); 651 if (!br_info->open_trunc && 652 (br_info->level == SMB2_OPLOCK_LEVEL_BATCH || 653 br_info->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) 654 rsp->OplockLevel = SMB2_OPLOCK_LEVEL_II; 655 else 656 rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE; 657 rsp->Reserved = 0; 658 rsp->Reserved2 = 0; 659 rsp->PersistentFid = fp->persistent_id; 660 rsp->VolatileFid = fp->volatile_id; 661 662 inc_rfc1001_len(work->response_buf, 24); 663 664 ksmbd_debug(OPLOCK, 665 "sending oplock break v_id %llu p_id = %llu lock level = %d\n", 666 rsp->VolatileFid, rsp->PersistentFid, rsp->OplockLevel); 667 668 ksmbd_fd_put(work, fp); 669 ksmbd_conn_write(work); 670 ksmbd_free_work_struct(work); 671 atomic_dec(&conn->r_count); 672} 673 674/** 675 * smb2_oplock_break_noti() - send smb2 exclusive/batch to level2 oplock 676 * break command from server to client 677 * @opinfo: oplock info object 678 * 679 * Return: 0 on success, otherwise error 680 */ 681static int smb2_oplock_break_noti(struct oplock_info *opinfo) 682{ 683 struct ksmbd_conn *conn = opinfo->conn; 684 struct oplock_break_info *br_info; 685 int ret = 0; 686 struct ksmbd_work *work = ksmbd_alloc_work_struct(); 687 688 if (!work) 689 return -ENOMEM; 690 691 br_info = kmalloc(sizeof(struct oplock_break_info), GFP_KERNEL); 692 if (!br_info) { 693 ksmbd_free_work_struct(work); 694 return -ENOMEM; 695 } 696 697 br_info->level = opinfo->level; 698 br_info->fid = opinfo->fid; 699 br_info->open_trunc = opinfo->open_trunc; 700 701 work->request_buf = (char *)br_info; 702 work->conn = conn; 703 work->sess = opinfo->sess; 704 705 atomic_inc(&conn->r_count); 706 if (opinfo->op_state == OPLOCK_ACK_WAIT) { 707 INIT_WORK(&work->work, __smb2_oplock_break_noti); 708 ksmbd_queue_work(work); 709 710 wait_for_break_ack(opinfo); 711 } else { 712 __smb2_oplock_break_noti(&work->work); 713 if (opinfo->level == SMB2_OPLOCK_LEVEL_II) 714 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; 715 } 716 return ret; 717} 718 719/** 720 * __smb2_lease_break_noti() - send lease break command from server 721 * to client 722 * @wk: smb work object 723 */ 724static void __smb2_lease_break_noti(struct work_struct *wk) 725{ 726 struct smb2_lease_break *rsp = NULL; 727 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); 728 struct lease_break_info *br_info = work->request_buf; 729 struct ksmbd_conn *conn = work->conn; 730 struct smb2_hdr *rsp_hdr; 731 732 if (allocate_oplock_break_buf(work)) { 733 ksmbd_debug(OPLOCK, "smb2_allocate_rsp_buf failed! "); 734 ksmbd_free_work_struct(work); 735 atomic_dec(&conn->r_count); 736 return; 737 } 738 739 rsp_hdr = smb2_get_msg(work->response_buf); 740 memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); 741 *(__be32 *)work->response_buf = 742 cpu_to_be32(conn->vals->header_size); 743 rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; 744 rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; 745 rsp_hdr->CreditRequest = cpu_to_le16(0); 746 rsp_hdr->Command = SMB2_OPLOCK_BREAK; 747 rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR); 748 rsp_hdr->NextCommand = 0; 749 rsp_hdr->MessageId = cpu_to_le64(-1); 750 rsp_hdr->Id.SyncId.ProcessId = 0; 751 rsp_hdr->Id.SyncId.TreeId = 0; 752 rsp_hdr->SessionId = 0; 753 memset(rsp_hdr->Signature, 0, 16); 754 755 rsp = smb2_get_msg(work->response_buf); 756 rsp->StructureSize = cpu_to_le16(44); 757 rsp->Epoch = br_info->epoch; 758 rsp->Flags = 0; 759 760 if (br_info->curr_state & (SMB2_LEASE_WRITE_CACHING_LE | 761 SMB2_LEASE_HANDLE_CACHING_LE)) 762 rsp->Flags = SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED; 763 764 memcpy(rsp->LeaseKey, br_info->lease_key, SMB2_LEASE_KEY_SIZE); 765 rsp->CurrentLeaseState = br_info->curr_state; 766 rsp->NewLeaseState = br_info->new_state; 767 rsp->BreakReason = 0; 768 rsp->AccessMaskHint = 0; 769 rsp->ShareMaskHint = 0; 770 771 inc_rfc1001_len(work->response_buf, 44); 772 773 ksmbd_conn_write(work); 774 ksmbd_free_work_struct(work); 775 atomic_dec(&conn->r_count); 776} 777 778/** 779 * smb2_lease_break_noti() - break lease when a new client request 780 * write lease 781 * @opinfo: conains lease state information 782 * 783 * Return: 0 on success, otherwise error 784 */ 785static int smb2_lease_break_noti(struct oplock_info *opinfo) 786{ 787 struct ksmbd_conn *conn = opinfo->conn; 788 struct list_head *tmp, *t; 789 struct ksmbd_work *work; 790 struct lease_break_info *br_info; 791 struct lease *lease = opinfo->o_lease; 792 793 work = ksmbd_alloc_work_struct(); 794 if (!work) 795 return -ENOMEM; 796 797 br_info = kmalloc(sizeof(struct lease_break_info), GFP_KERNEL); 798 if (!br_info) { 799 ksmbd_free_work_struct(work); 800 return -ENOMEM; 801 } 802 803 br_info->curr_state = lease->state; 804 br_info->new_state = lease->new_state; 805 if (lease->version == 2) 806 br_info->epoch = cpu_to_le16(++lease->epoch); 807 else 808 br_info->epoch = 0; 809 memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE); 810 811 work->request_buf = (char *)br_info; 812 work->conn = conn; 813 work->sess = opinfo->sess; 814 815 atomic_inc(&conn->r_count); 816 if (opinfo->op_state == OPLOCK_ACK_WAIT) { 817 list_for_each_safe(tmp, t, &opinfo->interim_list) { 818 struct ksmbd_work *in_work; 819 820 in_work = list_entry(tmp, struct ksmbd_work, 821 interim_entry); 822 setup_async_work(in_work, NULL, NULL); 823 smb2_send_interim_resp(in_work, STATUS_PENDING); 824 list_del(&in_work->interim_entry); 825 } 826 INIT_WORK(&work->work, __smb2_lease_break_noti); 827 ksmbd_queue_work(work); 828 wait_for_break_ack(opinfo); 829 } else { 830 __smb2_lease_break_noti(&work->work); 831 if (opinfo->o_lease->new_state == SMB2_LEASE_NONE_LE) { 832 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; 833 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; 834 } 835 } 836 return 0; 837} 838 839static void wait_lease_breaking(struct oplock_info *opinfo) 840{ 841 if (!opinfo->is_lease) 842 return; 843 844 wake_up_interruptible_all(&opinfo->oplock_brk); 845 if (atomic_read(&opinfo->breaking_cnt)) { 846 int ret = 0; 847 848 ret = wait_event_interruptible_timeout(opinfo->oplock_brk, 849 atomic_read(&opinfo->breaking_cnt) == 0, 850 HZ); 851 if (!ret) 852 atomic_set(&opinfo->breaking_cnt, 0); 853 } 854} 855 856static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level) 857{ 858 int err = 0; 859 860 /* Need to break exclusive/batch oplock, write lease or overwrite_if */ 861 ksmbd_debug(OPLOCK, 862 "request to send oplock(level : 0x%x) break notification\n", 863 brk_opinfo->level); 864 865 if (brk_opinfo->is_lease) { 866 struct lease *lease = brk_opinfo->o_lease; 867 868 atomic_inc(&brk_opinfo->breaking_cnt); 869 870 err = oplock_break_pending(brk_opinfo, req_op_level); 871 if (err) 872 return err < 0 ? err : 0; 873 874 if (brk_opinfo->open_trunc) { 875 /* 876 * Create overwrite break trigger the lease break to 877 * none. 878 */ 879 lease->new_state = SMB2_LEASE_NONE_LE; 880 } else { 881 if (lease->state & SMB2_LEASE_WRITE_CACHING_LE) { 882 if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE) 883 lease->new_state = 884 SMB2_LEASE_READ_CACHING_LE | 885 SMB2_LEASE_HANDLE_CACHING_LE; 886 else 887 lease->new_state = 888 SMB2_LEASE_READ_CACHING_LE; 889 } else { 890 if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE) 891 lease->new_state = 892 SMB2_LEASE_READ_CACHING_LE; 893 else 894 lease->new_state = SMB2_LEASE_NONE_LE; 895 } 896 } 897 898 if (lease->state & (SMB2_LEASE_WRITE_CACHING_LE | 899 SMB2_LEASE_HANDLE_CACHING_LE)) 900 brk_opinfo->op_state = OPLOCK_ACK_WAIT; 901 else 902 atomic_dec(&brk_opinfo->breaking_cnt); 903 } else { 904 err = oplock_break_pending(brk_opinfo, req_op_level); 905 if (err) 906 return err < 0 ? err : 0; 907 908 if (brk_opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || 909 brk_opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE) 910 brk_opinfo->op_state = OPLOCK_ACK_WAIT; 911 } 912 913 if (brk_opinfo->is_lease) 914 err = smb2_lease_break_noti(brk_opinfo); 915 else 916 err = smb2_oplock_break_noti(brk_opinfo); 917 918 ksmbd_debug(OPLOCK, "oplock granted = %d\n", brk_opinfo->level); 919 if (brk_opinfo->op_state == OPLOCK_CLOSING) 920 err = -ENOENT; 921 wake_up_oplock_break(brk_opinfo); 922 923 wait_lease_breaking(brk_opinfo); 924 925 return err; 926} 927 928void destroy_lease_table(struct ksmbd_conn *conn) 929{ 930 struct lease_table *lb, *lbtmp; 931 struct oplock_info *opinfo; 932 933 write_lock(&lease_list_lock); 934 if (list_empty(&lease_table_list)) { 935 write_unlock(&lease_list_lock); 936 return; 937 } 938 939 list_for_each_entry_safe(lb, lbtmp, &lease_table_list, l_entry) { 940 if (conn && memcmp(lb->client_guid, conn->ClientGUID, 941 SMB2_CLIENT_GUID_SIZE)) 942 continue; 943again: 944 rcu_read_lock(); 945 list_for_each_entry_rcu(opinfo, &lb->lease_list, 946 lease_entry) { 947 rcu_read_unlock(); 948 lease_del_list(opinfo); 949 goto again; 950 } 951 rcu_read_unlock(); 952 list_del(&lb->l_entry); 953 kfree(lb); 954 } 955 write_unlock(&lease_list_lock); 956} 957 958int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, 959 struct lease_ctx_info *lctx) 960{ 961 struct oplock_info *opinfo; 962 int err = 0; 963 struct lease_table *lb; 964 965 if (!lctx) 966 return err; 967 968 read_lock(&lease_list_lock); 969 if (list_empty(&lease_table_list)) { 970 read_unlock(&lease_list_lock); 971 return 0; 972 } 973 974 list_for_each_entry(lb, &lease_table_list, l_entry) { 975 if (!memcmp(lb->client_guid, sess->conn->ClientGUID, 976 SMB2_CLIENT_GUID_SIZE)) 977 goto found; 978 } 979 read_unlock(&lease_list_lock); 980 981 return 0; 982 983found: 984 rcu_read_lock(); 985 list_for_each_entry_rcu(opinfo, &lb->lease_list, lease_entry) { 986 if (!atomic_inc_not_zero(&opinfo->refcount)) 987 continue; 988 rcu_read_unlock(); 989 if (opinfo->o_fp->f_ci == ci) 990 goto op_next; 991 err = compare_guid_key(opinfo, sess->conn->ClientGUID, 992 lctx->lease_key); 993 if (err) { 994 err = -EINVAL; 995 ksmbd_debug(OPLOCK, 996 "found same lease key is already used in other files\n"); 997 opinfo_put(opinfo); 998 goto out; 999 } 1000op_next: 1001 opinfo_put(opinfo); 1002 rcu_read_lock(); 1003 } 1004 rcu_read_unlock(); 1005 1006out: 1007 read_unlock(&lease_list_lock); 1008 return err; 1009} 1010 1011static void copy_lease(struct oplock_info *op1, struct oplock_info *op2) 1012{ 1013 struct lease *lease1 = op1->o_lease; 1014 struct lease *lease2 = op2->o_lease; 1015 1016 op2->level = op1->level; 1017 lease2->state = lease1->state; 1018 memcpy(lease2->lease_key, lease1->lease_key, 1019 SMB2_LEASE_KEY_SIZE); 1020 lease2->duration = lease1->duration; 1021 lease2->flags = lease1->flags; 1022} 1023 1024static int add_lease_global_list(struct oplock_info *opinfo) 1025{ 1026 struct lease_table *lb; 1027 1028 read_lock(&lease_list_lock); 1029 list_for_each_entry(lb, &lease_table_list, l_entry) { 1030 if (!memcmp(lb->client_guid, opinfo->conn->ClientGUID, 1031 SMB2_CLIENT_GUID_SIZE)) { 1032 opinfo->o_lease->l_lb = lb; 1033 lease_add_list(opinfo); 1034 read_unlock(&lease_list_lock); 1035 return 0; 1036 } 1037 } 1038 read_unlock(&lease_list_lock); 1039 1040 lb = kmalloc(sizeof(struct lease_table), GFP_KERNEL); 1041 if (!lb) 1042 return -ENOMEM; 1043 1044 memcpy(lb->client_guid, opinfo->conn->ClientGUID, 1045 SMB2_CLIENT_GUID_SIZE); 1046 INIT_LIST_HEAD(&lb->lease_list); 1047 spin_lock_init(&lb->lb_lock); 1048 opinfo->o_lease->l_lb = lb; 1049 lease_add_list(opinfo); 1050 lb_add(lb); 1051 return 0; 1052} 1053 1054static void set_oplock_level(struct oplock_info *opinfo, int level, 1055 struct lease_ctx_info *lctx) 1056{ 1057 switch (level) { 1058 case SMB2_OPLOCK_LEVEL_BATCH: 1059 case SMB2_OPLOCK_LEVEL_EXCLUSIVE: 1060 grant_write_oplock(opinfo, level, lctx); 1061 break; 1062 case SMB2_OPLOCK_LEVEL_II: 1063 grant_read_oplock(opinfo, lctx); 1064 break; 1065 default: 1066 grant_none_oplock(opinfo, lctx); 1067 break; 1068 } 1069} 1070 1071/** 1072 * smb_grant_oplock() - handle oplock/lease request on file open 1073 * @work: smb work 1074 * @req_op_level: oplock level 1075 * @pid: id of open file 1076 * @fp: ksmbd file pointer 1077 * @tid: Tree id of connection 1078 * @lctx: lease context information on file open 1079 * @share_ret: share mode 1080 * 1081 * Return: 0 on success, otherwise error 1082 */ 1083int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, 1084 struct ksmbd_file *fp, __u16 tid, 1085 struct lease_ctx_info *lctx, int share_ret) 1086{ 1087 struct ksmbd_session *sess = work->sess; 1088 int err = 0; 1089 struct oplock_info *opinfo = NULL, *prev_opinfo = NULL; 1090 struct ksmbd_inode *ci = fp->f_ci; 1091 bool prev_op_has_lease; 1092 __le32 prev_op_state = 0; 1093 1094 /* not support directory lease */ 1095 if (S_ISDIR(file_inode(fp->filp)->i_mode)) 1096 return 0; 1097 1098 opinfo = alloc_opinfo(work, pid, tid); 1099 if (!opinfo) 1100 return -ENOMEM; 1101 1102 if (lctx) { 1103 err = alloc_lease(opinfo, lctx); 1104 if (err) 1105 goto err_out; 1106 opinfo->is_lease = 1; 1107 } 1108 1109 /* ci does not have any oplock */ 1110 if (!opinfo_count(fp)) 1111 goto set_lev; 1112 1113 /* grant none-oplock if second open is trunc */ 1114 if (fp->attrib_only && fp->cdoption != FILE_OVERWRITE_IF_LE && 1115 fp->cdoption != FILE_OVERWRITE_LE && 1116 fp->cdoption != FILE_SUPERSEDE_LE) { 1117 req_op_level = SMB2_OPLOCK_LEVEL_NONE; 1118 goto set_lev; 1119 } 1120 1121 if (lctx) { 1122 struct oplock_info *m_opinfo; 1123 1124 /* is lease already granted ? */ 1125 m_opinfo = same_client_has_lease(ci, sess->conn->ClientGUID, 1126 lctx); 1127 if (m_opinfo) { 1128 copy_lease(m_opinfo, opinfo); 1129 if (atomic_read(&m_opinfo->breaking_cnt)) 1130 opinfo->o_lease->flags = 1131 SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE; 1132 goto out; 1133 } 1134 } 1135 prev_opinfo = opinfo_get_list(ci); 1136 if (!prev_opinfo || 1137 (prev_opinfo->level == SMB2_OPLOCK_LEVEL_NONE && lctx)) 1138 goto set_lev; 1139 prev_op_has_lease = prev_opinfo->is_lease; 1140 if (prev_op_has_lease) 1141 prev_op_state = prev_opinfo->o_lease->state; 1142 1143 if (share_ret < 0 && 1144 prev_opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE) { 1145 err = share_ret; 1146 opinfo_put(prev_opinfo); 1147 goto err_out; 1148 } 1149 1150 if (prev_opinfo->level != SMB2_OPLOCK_LEVEL_BATCH && 1151 prev_opinfo->level != SMB2_OPLOCK_LEVEL_EXCLUSIVE) { 1152 opinfo_put(prev_opinfo); 1153 goto op_break_not_needed; 1154 } 1155 1156 list_add(&work->interim_entry, &prev_opinfo->interim_list); 1157 err = oplock_break(prev_opinfo, SMB2_OPLOCK_LEVEL_II); 1158 opinfo_put(prev_opinfo); 1159 if (err == -ENOENT) 1160 goto set_lev; 1161 /* Check all oplock was freed by close */ 1162 else if (err < 0) 1163 goto err_out; 1164 1165op_break_not_needed: 1166 if (share_ret < 0) { 1167 err = share_ret; 1168 goto err_out; 1169 } 1170 1171 if (req_op_level != SMB2_OPLOCK_LEVEL_NONE) 1172 req_op_level = SMB2_OPLOCK_LEVEL_II; 1173 1174 /* grant fixed oplock on stacked locking between lease and oplock */ 1175 if (prev_op_has_lease && !lctx) 1176 if (prev_op_state & SMB2_LEASE_HANDLE_CACHING_LE) 1177 req_op_level = SMB2_OPLOCK_LEVEL_NONE; 1178 1179 if (!prev_op_has_lease && lctx) { 1180 req_op_level = SMB2_OPLOCK_LEVEL_II; 1181 lctx->req_state = SMB2_LEASE_READ_CACHING_LE; 1182 } 1183 1184set_lev: 1185 set_oplock_level(opinfo, req_op_level, lctx); 1186 1187out: 1188 rcu_assign_pointer(fp->f_opinfo, opinfo); 1189 opinfo->o_fp = fp; 1190 1191 opinfo_count_inc(fp); 1192 opinfo_add(opinfo); 1193 if (opinfo->is_lease) { 1194 err = add_lease_global_list(opinfo); 1195 if (err) 1196 goto err_out; 1197 } 1198 1199 return 0; 1200err_out: 1201 free_opinfo(opinfo); 1202 return err; 1203} 1204 1205/** 1206 * smb_break_all_write_oplock() - break batch/exclusive oplock to level2 1207 * @work: smb work 1208 * @fp: ksmbd file pointer 1209 * @is_trunc: truncate on open 1210 */ 1211static void smb_break_all_write_oplock(struct ksmbd_work *work, 1212 struct ksmbd_file *fp, int is_trunc) 1213{ 1214 struct oplock_info *brk_opinfo; 1215 1216 brk_opinfo = opinfo_get_list(fp->f_ci); 1217 if (!brk_opinfo) 1218 return; 1219 if (brk_opinfo->level != SMB2_OPLOCK_LEVEL_BATCH && 1220 brk_opinfo->level != SMB2_OPLOCK_LEVEL_EXCLUSIVE) { 1221 opinfo_put(brk_opinfo); 1222 return; 1223 } 1224 1225 brk_opinfo->open_trunc = is_trunc; 1226 list_add(&work->interim_entry, &brk_opinfo->interim_list); 1227 oplock_break(brk_opinfo, SMB2_OPLOCK_LEVEL_II); 1228 opinfo_put(brk_opinfo); 1229} 1230 1231/** 1232 * smb_break_all_levII_oplock() - send level2 oplock or read lease break command 1233 * from server to client 1234 * @work: smb work 1235 * @fp: ksmbd file pointer 1236 * @is_trunc: truncate on open 1237 */ 1238void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp, 1239 int is_trunc) 1240{ 1241 struct oplock_info *op, *brk_op; 1242 struct ksmbd_inode *ci; 1243 struct ksmbd_conn *conn = work->sess->conn; 1244 1245 if (!test_share_config_flag(work->tcon->share_conf, 1246 KSMBD_SHARE_FLAG_OPLOCKS)) 1247 return; 1248 1249 ci = fp->f_ci; 1250 op = opinfo_get(fp); 1251 1252 rcu_read_lock(); 1253 list_for_each_entry_rcu(brk_op, &ci->m_op_list, op_entry) { 1254 if (!atomic_inc_not_zero(&brk_op->refcount)) 1255 continue; 1256 rcu_read_unlock(); 1257 if (brk_op->is_lease && (brk_op->o_lease->state & 1258 (~(SMB2_LEASE_READ_CACHING_LE | 1259 SMB2_LEASE_HANDLE_CACHING_LE)))) { 1260 ksmbd_debug(OPLOCK, "unexpected lease state(0x%x)\n", 1261 brk_op->o_lease->state); 1262 goto next; 1263 } else if (brk_op->level != 1264 SMB2_OPLOCK_LEVEL_II) { 1265 ksmbd_debug(OPLOCK, "unexpected oplock(0x%x)\n", 1266 brk_op->level); 1267 goto next; 1268 } 1269 1270 /* Skip oplock being break to none */ 1271 if (brk_op->is_lease && 1272 brk_op->o_lease->new_state == SMB2_LEASE_NONE_LE && 1273 atomic_read(&brk_op->breaking_cnt)) 1274 goto next; 1275 1276 if (op && op->is_lease && brk_op->is_lease && 1277 !memcmp(conn->ClientGUID, brk_op->conn->ClientGUID, 1278 SMB2_CLIENT_GUID_SIZE) && 1279 !memcmp(op->o_lease->lease_key, brk_op->o_lease->lease_key, 1280 SMB2_LEASE_KEY_SIZE)) 1281 goto next; 1282 brk_op->open_trunc = is_trunc; 1283 oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE); 1284next: 1285 opinfo_put(brk_op); 1286 rcu_read_lock(); 1287 } 1288 rcu_read_unlock(); 1289 1290 if (op) 1291 opinfo_put(op); 1292} 1293 1294/** 1295 * smb_break_all_oplock() - break both batch/exclusive and level2 oplock 1296 * @work: smb work 1297 * @fp: ksmbd file pointer 1298 */ 1299void smb_break_all_oplock(struct ksmbd_work *work, struct ksmbd_file *fp) 1300{ 1301 if (!test_share_config_flag(work->tcon->share_conf, 1302 KSMBD_SHARE_FLAG_OPLOCKS)) 1303 return; 1304 1305 smb_break_all_write_oplock(work, fp, 1); 1306 smb_break_all_levII_oplock(work, fp, 1); 1307} 1308 1309/** 1310 * smb2_map_lease_to_oplock() - map lease state to corresponding oplock type 1311 * @lease_state: lease type 1312 * 1313 * Return: 0 if no mapping, otherwise corresponding oplock type 1314 */ 1315__u8 smb2_map_lease_to_oplock(__le32 lease_state) 1316{ 1317 if (lease_state == (SMB2_LEASE_HANDLE_CACHING_LE | 1318 SMB2_LEASE_READ_CACHING_LE | 1319 SMB2_LEASE_WRITE_CACHING_LE)) { 1320 return SMB2_OPLOCK_LEVEL_BATCH; 1321 } else if (lease_state != SMB2_LEASE_WRITE_CACHING_LE && 1322 lease_state & SMB2_LEASE_WRITE_CACHING_LE) { 1323 if (!(lease_state & SMB2_LEASE_HANDLE_CACHING_LE)) 1324 return SMB2_OPLOCK_LEVEL_EXCLUSIVE; 1325 } else if (lease_state & SMB2_LEASE_READ_CACHING_LE) { 1326 return SMB2_OPLOCK_LEVEL_II; 1327 } 1328 return 0; 1329} 1330 1331/** 1332 * create_lease_buf() - create lease context for open cmd response 1333 * @rbuf: buffer to create lease context response 1334 * @lease: buffer to stored parsed lease state information 1335 */ 1336void create_lease_buf(u8 *rbuf, struct lease *lease) 1337{ 1338 if (lease->version == 2) { 1339 struct create_lease_v2 *buf = (struct create_lease_v2 *)rbuf; 1340 1341 memset(buf, 0, sizeof(struct create_lease_v2)); 1342 memcpy(buf->lcontext.LeaseKey, lease->lease_key, 1343 SMB2_LEASE_KEY_SIZE); 1344 buf->lcontext.LeaseFlags = lease->flags; 1345 buf->lcontext.LeaseState = lease->state; 1346 memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key, 1347 SMB2_LEASE_KEY_SIZE); 1348 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1349 (struct create_lease_v2, lcontext)); 1350 buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2)); 1351 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1352 (struct create_lease_v2, Name)); 1353 buf->ccontext.NameLength = cpu_to_le16(4); 1354 buf->Name[0] = 'R'; 1355 buf->Name[1] = 'q'; 1356 buf->Name[2] = 'L'; 1357 buf->Name[3] = 's'; 1358 } else { 1359 struct create_lease *buf = (struct create_lease *)rbuf; 1360 1361 memset(buf, 0, sizeof(struct create_lease)); 1362 memcpy(buf->lcontext.LeaseKey, lease->lease_key, SMB2_LEASE_KEY_SIZE); 1363 buf->lcontext.LeaseFlags = lease->flags; 1364 buf->lcontext.LeaseState = lease->state; 1365 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1366 (struct create_lease, lcontext)); 1367 buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context)); 1368 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1369 (struct create_lease, Name)); 1370 buf->ccontext.NameLength = cpu_to_le16(4); 1371 buf->Name[0] = 'R'; 1372 buf->Name[1] = 'q'; 1373 buf->Name[2] = 'L'; 1374 buf->Name[3] = 's'; 1375 } 1376} 1377 1378/** 1379 * parse_lease_state() - parse lease context containted in file open request 1380 * @open_req: buffer containing smb2 file open(create) request 1381 * 1382 * Return: oplock state, -ENOENT if create lease context not found 1383 */ 1384struct lease_ctx_info *parse_lease_state(void *open_req) 1385{ 1386 char *data_offset; 1387 struct create_context *cc; 1388 unsigned int next = 0; 1389 char *name; 1390 bool found = false; 1391 struct smb2_create_req *req = (struct smb2_create_req *)open_req; 1392 struct lease_ctx_info *lreq = kzalloc(sizeof(struct lease_ctx_info), 1393 GFP_KERNEL); 1394 if (!lreq) 1395 return NULL; 1396 1397 data_offset = (char *)req + le32_to_cpu(req->CreateContextsOffset); 1398 cc = (struct create_context *)data_offset; 1399 do { 1400 cc = (struct create_context *)((char *)cc + next); 1401 name = le16_to_cpu(cc->NameOffset) + (char *)cc; 1402 if (le16_to_cpu(cc->NameLength) != 4 || 1403 strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) { 1404 next = le32_to_cpu(cc->Next); 1405 continue; 1406 } 1407 found = true; 1408 break; 1409 } while (next != 0); 1410 1411 if (found) { 1412 if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) { 1413 struct create_lease_v2 *lc = (struct create_lease_v2 *)cc; 1414 1415 memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); 1416 lreq->req_state = lc->lcontext.LeaseState; 1417 lreq->flags = lc->lcontext.LeaseFlags; 1418 lreq->duration = lc->lcontext.LeaseDuration; 1419 memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey, 1420 SMB2_LEASE_KEY_SIZE); 1421 lreq->version = 2; 1422 } else { 1423 struct create_lease *lc = (struct create_lease *)cc; 1424 1425 memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); 1426 lreq->req_state = lc->lcontext.LeaseState; 1427 lreq->flags = lc->lcontext.LeaseFlags; 1428 lreq->duration = lc->lcontext.LeaseDuration; 1429 lreq->version = 1; 1430 } 1431 return lreq; 1432 } 1433 1434 kfree(lreq); 1435 return NULL; 1436} 1437 1438/** 1439 * smb2_find_context_vals() - find a particular context info in open request 1440 * @open_req: buffer containing smb2 file open(create) request 1441 * @tag: context name to search for 1442 * 1443 * Return: pointer to requested context, NULL if @str context not found 1444 * or error pointer if name length is invalid. 1445 */ 1446struct create_context *smb2_find_context_vals(void *open_req, const char *tag) 1447{ 1448 struct create_context *cc; 1449 unsigned int next = 0; 1450 char *name; 1451 struct smb2_create_req *req = (struct smb2_create_req *)open_req; 1452 unsigned int remain_len, name_off, name_len, value_off, value_len, 1453 cc_len; 1454 1455 /* 1456 * CreateContextsOffset and CreateContextsLength are guaranteed to 1457 * be valid because of ksmbd_smb2_check_message(). 1458 */ 1459 cc = (struct create_context *)((char *)req + 1460 le32_to_cpu(req->CreateContextsOffset)); 1461 remain_len = le32_to_cpu(req->CreateContextsLength); 1462 do { 1463 cc = (struct create_context *)((char *)cc + next); 1464 if (remain_len < offsetof(struct create_context, Buffer)) 1465 return ERR_PTR(-EINVAL); 1466 1467 next = le32_to_cpu(cc->Next); 1468 name_off = le16_to_cpu(cc->NameOffset); 1469 name_len = le16_to_cpu(cc->NameLength); 1470 value_off = le16_to_cpu(cc->DataOffset); 1471 value_len = le32_to_cpu(cc->DataLength); 1472 cc_len = next ? next : remain_len; 1473 1474 if ((next & 0x7) != 0 || 1475 next > remain_len || 1476 name_off != offsetof(struct create_context, Buffer) || 1477 name_len < 4 || 1478 name_off + name_len > cc_len || 1479 (value_off & 0x7) != 0 || 1480 (value_off && (value_off < name_off + name_len)) || 1481 ((u64)value_off + value_len > cc_len)) 1482 return ERR_PTR(-EINVAL); 1483 1484 name = (char *)cc + name_off; 1485 if (memcmp(name, tag, name_len) == 0) 1486 return cc; 1487 1488 remain_len -= next; 1489 } while (next != 0); 1490 1491 return NULL; 1492} 1493 1494/** 1495 * create_durable_rsp_buf() - create durable handle context 1496 * @cc: buffer to create durable context response 1497 */ 1498void create_durable_rsp_buf(char *cc) 1499{ 1500 struct create_durable_rsp *buf; 1501 1502 buf = (struct create_durable_rsp *)cc; 1503 memset(buf, 0, sizeof(struct create_durable_rsp)); 1504 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1505 (struct create_durable_rsp, Data)); 1506 buf->ccontext.DataLength = cpu_to_le32(8); 1507 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1508 (struct create_durable_rsp, Name)); 1509 buf->ccontext.NameLength = cpu_to_le16(4); 1510 /* SMB2_CREATE_DURABLE_HANDLE_RESPONSE is "DHnQ" */ 1511 buf->Name[0] = 'D'; 1512 buf->Name[1] = 'H'; 1513 buf->Name[2] = 'n'; 1514 buf->Name[3] = 'Q'; 1515} 1516 1517/** 1518 * create_durable_v2_rsp_buf() - create durable handle v2 context 1519 * @cc: buffer to create durable context response 1520 * @fp: ksmbd file pointer 1521 */ 1522void create_durable_v2_rsp_buf(char *cc, struct ksmbd_file *fp) 1523{ 1524 struct create_durable_v2_rsp *buf; 1525 1526 buf = (struct create_durable_v2_rsp *)cc; 1527 memset(buf, 0, sizeof(struct create_durable_rsp)); 1528 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1529 (struct create_durable_rsp, Data)); 1530 buf->ccontext.DataLength = cpu_to_le32(8); 1531 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1532 (struct create_durable_rsp, Name)); 1533 buf->ccontext.NameLength = cpu_to_le16(4); 1534 /* SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2 is "DH2Q" */ 1535 buf->Name[0] = 'D'; 1536 buf->Name[1] = 'H'; 1537 buf->Name[2] = '2'; 1538 buf->Name[3] = 'Q'; 1539 1540 buf->Timeout = cpu_to_le32(fp->durable_timeout); 1541} 1542 1543/** 1544 * create_mxac_rsp_buf() - create query maximal access context 1545 * @cc: buffer to create maximal access context response 1546 * @maximal_access: maximal access 1547 */ 1548void create_mxac_rsp_buf(char *cc, int maximal_access) 1549{ 1550 struct create_mxac_rsp *buf; 1551 1552 buf = (struct create_mxac_rsp *)cc; 1553 memset(buf, 0, sizeof(struct create_mxac_rsp)); 1554 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1555 (struct create_mxac_rsp, QueryStatus)); 1556 buf->ccontext.DataLength = cpu_to_le32(8); 1557 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1558 (struct create_mxac_rsp, Name)); 1559 buf->ccontext.NameLength = cpu_to_le16(4); 1560 /* SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE is "MxAc" */ 1561 buf->Name[0] = 'M'; 1562 buf->Name[1] = 'x'; 1563 buf->Name[2] = 'A'; 1564 buf->Name[3] = 'c'; 1565 1566 buf->QueryStatus = STATUS_SUCCESS; 1567 buf->MaximalAccess = cpu_to_le32(maximal_access); 1568} 1569 1570void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id) 1571{ 1572 struct create_disk_id_rsp *buf; 1573 1574 buf = (struct create_disk_id_rsp *)cc; 1575 memset(buf, 0, sizeof(struct create_disk_id_rsp)); 1576 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1577 (struct create_disk_id_rsp, DiskFileId)); 1578 buf->ccontext.DataLength = cpu_to_le32(32); 1579 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1580 (struct create_mxac_rsp, Name)); 1581 buf->ccontext.NameLength = cpu_to_le16(4); 1582 /* SMB2_CREATE_QUERY_ON_DISK_ID_RESPONSE is "QFid" */ 1583 buf->Name[0] = 'Q'; 1584 buf->Name[1] = 'F'; 1585 buf->Name[2] = 'i'; 1586 buf->Name[3] = 'd'; 1587 1588 buf->DiskFileId = cpu_to_le64(file_id); 1589 buf->VolumeId = cpu_to_le64(vol_id); 1590} 1591 1592/** 1593 * create_posix_rsp_buf() - create posix extension context 1594 * @cc: buffer to create posix on posix response 1595 * @fp: ksmbd file pointer 1596 */ 1597void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp) 1598{ 1599 struct create_posix_rsp *buf; 1600 struct inode *inode = file_inode(fp->filp); 1601 struct user_namespace *user_ns = file_mnt_user_ns(fp->filp); 1602 1603 buf = (struct create_posix_rsp *)cc; 1604 memset(buf, 0, sizeof(struct create_posix_rsp)); 1605 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1606 (struct create_posix_rsp, nlink)); 1607 buf->ccontext.DataLength = cpu_to_le32(52); 1608 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1609 (struct create_posix_rsp, Name)); 1610 buf->ccontext.NameLength = cpu_to_le16(POSIX_CTXT_DATA_LEN); 1611 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */ 1612 buf->Name[0] = 0x93; 1613 buf->Name[1] = 0xAD; 1614 buf->Name[2] = 0x25; 1615 buf->Name[3] = 0x50; 1616 buf->Name[4] = 0x9C; 1617 buf->Name[5] = 0xB4; 1618 buf->Name[6] = 0x11; 1619 buf->Name[7] = 0xE7; 1620 buf->Name[8] = 0xB4; 1621 buf->Name[9] = 0x23; 1622 buf->Name[10] = 0x83; 1623 buf->Name[11] = 0xDE; 1624 buf->Name[12] = 0x96; 1625 buf->Name[13] = 0x8B; 1626 buf->Name[14] = 0xCD; 1627 buf->Name[15] = 0x7C; 1628 1629 buf->nlink = cpu_to_le32(inode->i_nlink); 1630 buf->reparse_tag = cpu_to_le32(fp->volatile_id); 1631 buf->mode = cpu_to_le32(inode->i_mode); 1632 id_to_sid(from_kuid_munged(&init_user_ns, 1633 i_uid_into_mnt(user_ns, inode)), 1634 SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]); 1635 id_to_sid(from_kgid_munged(&init_user_ns, 1636 i_gid_into_mnt(user_ns, inode)), 1637 SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]); 1638} 1639 1640/* 1641 * Find lease object(opinfo) for given lease key/fid from lease 1642 * break/file close path. 1643 */ 1644/** 1645 * lookup_lease_in_table() - find a matching lease info object 1646 * @conn: connection instance 1647 * @lease_key: lease key to be searched for 1648 * 1649 * Return: opinfo if found matching opinfo, otherwise NULL 1650 */ 1651struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, 1652 char *lease_key) 1653{ 1654 struct oplock_info *opinfo = NULL, *ret_op = NULL; 1655 struct lease_table *lt; 1656 int ret; 1657 1658 read_lock(&lease_list_lock); 1659 list_for_each_entry(lt, &lease_table_list, l_entry) { 1660 if (!memcmp(lt->client_guid, conn->ClientGUID, 1661 SMB2_CLIENT_GUID_SIZE)) 1662 goto found; 1663 } 1664 1665 read_unlock(&lease_list_lock); 1666 return NULL; 1667 1668found: 1669 rcu_read_lock(); 1670 list_for_each_entry_rcu(opinfo, <->lease_list, lease_entry) { 1671 if (!atomic_inc_not_zero(&opinfo->refcount)) 1672 continue; 1673 rcu_read_unlock(); 1674 if (!opinfo->op_state || opinfo->op_state == OPLOCK_CLOSING) 1675 goto op_next; 1676 if (!(opinfo->o_lease->state & 1677 (SMB2_LEASE_HANDLE_CACHING_LE | 1678 SMB2_LEASE_WRITE_CACHING_LE))) 1679 goto op_next; 1680 ret = compare_guid_key(opinfo, conn->ClientGUID, 1681 lease_key); 1682 if (ret) { 1683 ksmbd_debug(OPLOCK, "found opinfo\n"); 1684 ret_op = opinfo; 1685 goto out; 1686 } 1687op_next: 1688 opinfo_put(opinfo); 1689 rcu_read_lock(); 1690 } 1691 rcu_read_unlock(); 1692 1693out: 1694 read_unlock(&lease_list_lock); 1695 return ret_op; 1696}