linux/fs/ksmbd/oplock.c
<<
>>
Prefs
   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 = work->response_buf;
 633        memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
 634        rsp_hdr->smb2_buf_length =
 635                cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals));
 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 = 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 = cpu_to_le64(fp->persistent_id);
 660        rsp->VolatileFid = cpu_to_le64(fp->volatile_id);
 661
 662        inc_rfc1001_len(rsp, 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 = work->response_buf;
 740        memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
 741        rsp_hdr->smb2_buf_length =
 742                cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals));
 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 = 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(rsp, 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        char *LeaseKey = (char *)&lease->lease_key;
1339
1340        if (lease->version == 2) {
1341                struct create_lease_v2 *buf = (struct create_lease_v2 *)rbuf;
1342                char *ParentLeaseKey = (char *)&lease->parent_lease_key;
1343
1344                memset(buf, 0, sizeof(struct create_lease_v2));
1345                buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
1346                buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
1347                buf->lcontext.LeaseFlags = lease->flags;
1348                buf->lcontext.LeaseState = lease->state;
1349                buf->lcontext.ParentLeaseKeyLow = *((__le64 *)ParentLeaseKey);
1350                buf->lcontext.ParentLeaseKeyHigh = *((__le64 *)(ParentLeaseKey + 8));
1351                buf->ccontext.DataOffset = cpu_to_le16(offsetof
1352                                (struct create_lease_v2, lcontext));
1353                buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
1354                buf->ccontext.NameOffset = cpu_to_le16(offsetof
1355                                (struct create_lease_v2, Name));
1356                buf->ccontext.NameLength = cpu_to_le16(4);
1357                buf->Name[0] = 'R';
1358                buf->Name[1] = 'q';
1359                buf->Name[2] = 'L';
1360                buf->Name[3] = 's';
1361        } else {
1362                struct create_lease *buf = (struct create_lease *)rbuf;
1363
1364                memset(buf, 0, sizeof(struct create_lease));
1365                buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
1366                buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
1367                buf->lcontext.LeaseFlags = lease->flags;
1368                buf->lcontext.LeaseState = lease->state;
1369                buf->ccontext.DataOffset = cpu_to_le16(offsetof
1370                                (struct create_lease, lcontext));
1371                buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
1372                buf->ccontext.NameOffset = cpu_to_le16(offsetof
1373                                (struct create_lease, Name));
1374                buf->ccontext.NameLength = cpu_to_le16(4);
1375                buf->Name[0] = 'R';
1376                buf->Name[1] = 'q';
1377                buf->Name[2] = 'L';
1378                buf->Name[3] = 's';
1379        }
1380}
1381
1382/**
1383 * parse_lease_state() - parse lease context containted in file open request
1384 * @open_req:   buffer containing smb2 file open(create) request
1385 *
1386 * Return:  oplock state, -ENOENT if create lease context not found
1387 */
1388struct lease_ctx_info *parse_lease_state(void *open_req)
1389{
1390        char *data_offset;
1391        struct create_context *cc;
1392        unsigned int next = 0;
1393        char *name;
1394        bool found = false;
1395        struct smb2_create_req *req = (struct smb2_create_req *)open_req;
1396        struct lease_ctx_info *lreq = kzalloc(sizeof(struct lease_ctx_info),
1397                GFP_KERNEL);
1398        if (!lreq)
1399                return NULL;
1400
1401        data_offset = (char *)req + 4 + le32_to_cpu(req->CreateContextsOffset);
1402        cc = (struct create_context *)data_offset;
1403        do {
1404                cc = (struct create_context *)((char *)cc + next);
1405                name = le16_to_cpu(cc->NameOffset) + (char *)cc;
1406                if (le16_to_cpu(cc->NameLength) != 4 ||
1407                    strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
1408                        next = le32_to_cpu(cc->Next);
1409                        continue;
1410                }
1411                found = true;
1412                break;
1413        } while (next != 0);
1414
1415        if (found) {
1416                if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
1417                        struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
1418
1419                        *((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
1420                        *((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
1421                        lreq->req_state = lc->lcontext.LeaseState;
1422                        lreq->flags = lc->lcontext.LeaseFlags;
1423                        lreq->duration = lc->lcontext.LeaseDuration;
1424                        *((__le64 *)lreq->parent_lease_key) = lc->lcontext.ParentLeaseKeyLow;
1425                        *((__le64 *)(lreq->parent_lease_key + 8)) = lc->lcontext.ParentLeaseKeyHigh;
1426                        lreq->version = 2;
1427                } else {
1428                        struct create_lease *lc = (struct create_lease *)cc;
1429
1430                        *((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
1431                        *((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
1432                        lreq->req_state = lc->lcontext.LeaseState;
1433                        lreq->flags = lc->lcontext.LeaseFlags;
1434                        lreq->duration = lc->lcontext.LeaseDuration;
1435                        lreq->version = 1;
1436                }
1437                return lreq;
1438        }
1439
1440        kfree(lreq);
1441        return NULL;
1442}
1443
1444/**
1445 * smb2_find_context_vals() - find a particular context info in open request
1446 * @open_req:   buffer containing smb2 file open(create) request
1447 * @tag:        context name to search for
1448 *
1449 * Return:      pointer to requested context, NULL if @str context not found
1450 *              or error pointer if name length is invalid.
1451 */
1452struct create_context *smb2_find_context_vals(void *open_req, const char *tag)
1453{
1454        struct create_context *cc;
1455        unsigned int next = 0;
1456        char *name;
1457        struct smb2_create_req *req = (struct smb2_create_req *)open_req;
1458        unsigned int remain_len, name_off, name_len, value_off, value_len,
1459                     cc_len;
1460
1461        /*
1462         * CreateContextsOffset and CreateContextsLength are guaranteed to
1463         * be valid because of ksmbd_smb2_check_message().
1464         */
1465        cc = (struct create_context *)((char *)req + 4 +
1466                                       le32_to_cpu(req->CreateContextsOffset));
1467        remain_len = le32_to_cpu(req->CreateContextsLength);
1468        do {
1469                cc = (struct create_context *)((char *)cc + next);
1470                if (remain_len < offsetof(struct create_context, Buffer))
1471                        return ERR_PTR(-EINVAL);
1472
1473                next = le32_to_cpu(cc->Next);
1474                name_off = le16_to_cpu(cc->NameOffset);
1475                name_len = le16_to_cpu(cc->NameLength);
1476                value_off = le16_to_cpu(cc->DataOffset);
1477                value_len = le32_to_cpu(cc->DataLength);
1478                cc_len = next ? next : remain_len;
1479
1480                if ((next & 0x7) != 0 ||
1481                    next > remain_len ||
1482                    name_off != offsetof(struct create_context, Buffer) ||
1483                    name_len < 4 ||
1484                    name_off + name_len > cc_len ||
1485                    (value_off & 0x7) != 0 ||
1486                    (value_off && (value_off < name_off + name_len)) ||
1487                    ((u64)value_off + value_len > cc_len))
1488                        return ERR_PTR(-EINVAL);
1489
1490                name = (char *)cc + name_off;
1491                if (memcmp(name, tag, name_len) == 0)
1492                        return cc;
1493
1494                remain_len -= next;
1495        } while (next != 0);
1496
1497        return NULL;
1498}
1499
1500/**
1501 * create_durable_rsp_buf() - create durable handle context
1502 * @cc: buffer to create durable context response
1503 */
1504void create_durable_rsp_buf(char *cc)
1505{
1506        struct create_durable_rsp *buf;
1507
1508        buf = (struct create_durable_rsp *)cc;
1509        memset(buf, 0, sizeof(struct create_durable_rsp));
1510        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1511                        (struct create_durable_rsp, Data));
1512        buf->ccontext.DataLength = cpu_to_le32(8);
1513        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1514                        (struct create_durable_rsp, Name));
1515        buf->ccontext.NameLength = cpu_to_le16(4);
1516        /* SMB2_CREATE_DURABLE_HANDLE_RESPONSE is "DHnQ" */
1517        buf->Name[0] = 'D';
1518        buf->Name[1] = 'H';
1519        buf->Name[2] = 'n';
1520        buf->Name[3] = 'Q';
1521}
1522
1523/**
1524 * create_durable_v2_rsp_buf() - create durable handle v2 context
1525 * @cc: buffer to create durable context response
1526 * @fp: ksmbd file pointer
1527 */
1528void create_durable_v2_rsp_buf(char *cc, struct ksmbd_file *fp)
1529{
1530        struct create_durable_v2_rsp *buf;
1531
1532        buf = (struct create_durable_v2_rsp *)cc;
1533        memset(buf, 0, sizeof(struct create_durable_rsp));
1534        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1535                        (struct create_durable_rsp, Data));
1536        buf->ccontext.DataLength = cpu_to_le32(8);
1537        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1538                        (struct create_durable_rsp, Name));
1539        buf->ccontext.NameLength = cpu_to_le16(4);
1540        /* SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2 is "DH2Q" */
1541        buf->Name[0] = 'D';
1542        buf->Name[1] = 'H';
1543        buf->Name[2] = '2';
1544        buf->Name[3] = 'Q';
1545
1546        buf->Timeout = cpu_to_le32(fp->durable_timeout);
1547}
1548
1549/**
1550 * create_mxac_rsp_buf() - create query maximal access context
1551 * @cc:                 buffer to create maximal access context response
1552 * @maximal_access:     maximal access
1553 */
1554void create_mxac_rsp_buf(char *cc, int maximal_access)
1555{
1556        struct create_mxac_rsp *buf;
1557
1558        buf = (struct create_mxac_rsp *)cc;
1559        memset(buf, 0, sizeof(struct create_mxac_rsp));
1560        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1561                        (struct create_mxac_rsp, QueryStatus));
1562        buf->ccontext.DataLength = cpu_to_le32(8);
1563        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1564                        (struct create_mxac_rsp, Name));
1565        buf->ccontext.NameLength = cpu_to_le16(4);
1566        /* SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE is "MxAc" */
1567        buf->Name[0] = 'M';
1568        buf->Name[1] = 'x';
1569        buf->Name[2] = 'A';
1570        buf->Name[3] = 'c';
1571
1572        buf->QueryStatus = STATUS_SUCCESS;
1573        buf->MaximalAccess = cpu_to_le32(maximal_access);
1574}
1575
1576void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id)
1577{
1578        struct create_disk_id_rsp *buf;
1579
1580        buf = (struct create_disk_id_rsp *)cc;
1581        memset(buf, 0, sizeof(struct create_disk_id_rsp));
1582        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1583                        (struct create_disk_id_rsp, DiskFileId));
1584        buf->ccontext.DataLength = cpu_to_le32(32);
1585        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1586                        (struct create_mxac_rsp, Name));
1587        buf->ccontext.NameLength = cpu_to_le16(4);
1588        /* SMB2_CREATE_QUERY_ON_DISK_ID_RESPONSE is "QFid" */
1589        buf->Name[0] = 'Q';
1590        buf->Name[1] = 'F';
1591        buf->Name[2] = 'i';
1592        buf->Name[3] = 'd';
1593
1594        buf->DiskFileId = cpu_to_le64(file_id);
1595        buf->VolumeId = cpu_to_le64(vol_id);
1596}
1597
1598/**
1599 * create_posix_rsp_buf() - create posix extension context
1600 * @cc: buffer to create posix on posix response
1601 * @fp: ksmbd file pointer
1602 */
1603void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp)
1604{
1605        struct create_posix_rsp *buf;
1606        struct inode *inode = file_inode(fp->filp);
1607        struct user_namespace *user_ns = file_mnt_user_ns(fp->filp);
1608
1609        buf = (struct create_posix_rsp *)cc;
1610        memset(buf, 0, sizeof(struct create_posix_rsp));
1611        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1612                        (struct create_posix_rsp, nlink));
1613        buf->ccontext.DataLength = cpu_to_le32(52);
1614        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1615                        (struct create_posix_rsp, Name));
1616        buf->ccontext.NameLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
1617        /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
1618        buf->Name[0] = 0x93;
1619        buf->Name[1] = 0xAD;
1620        buf->Name[2] = 0x25;
1621        buf->Name[3] = 0x50;
1622        buf->Name[4] = 0x9C;
1623        buf->Name[5] = 0xB4;
1624        buf->Name[6] = 0x11;
1625        buf->Name[7] = 0xE7;
1626        buf->Name[8] = 0xB4;
1627        buf->Name[9] = 0x23;
1628        buf->Name[10] = 0x83;
1629        buf->Name[11] = 0xDE;
1630        buf->Name[12] = 0x96;
1631        buf->Name[13] = 0x8B;
1632        buf->Name[14] = 0xCD;
1633        buf->Name[15] = 0x7C;
1634
1635        buf->nlink = cpu_to_le32(inode->i_nlink);
1636        buf->reparse_tag = cpu_to_le32(fp->volatile_id);
1637        buf->mode = cpu_to_le32(inode->i_mode);
1638        id_to_sid(from_kuid_munged(&init_user_ns,
1639                                   i_uid_into_mnt(user_ns, inode)),
1640                  SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]);
1641        id_to_sid(from_kgid_munged(&init_user_ns,
1642                                   i_gid_into_mnt(user_ns, inode)),
1643                  SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]);
1644}
1645
1646/*
1647 * Find lease object(opinfo) for given lease key/fid from lease
1648 * break/file close path.
1649 */
1650/**
1651 * lookup_lease_in_table() - find a matching lease info object
1652 * @conn:       connection instance
1653 * @lease_key:  lease key to be searched for
1654 *
1655 * Return:      opinfo if found matching opinfo, otherwise NULL
1656 */
1657struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
1658                                          char *lease_key)
1659{
1660        struct oplock_info *opinfo = NULL, *ret_op = NULL;
1661        struct lease_table *lt;
1662        int ret;
1663
1664        read_lock(&lease_list_lock);
1665        list_for_each_entry(lt, &lease_table_list, l_entry) {
1666                if (!memcmp(lt->client_guid, conn->ClientGUID,
1667                            SMB2_CLIENT_GUID_SIZE))
1668                        goto found;
1669        }
1670
1671        read_unlock(&lease_list_lock);
1672        return NULL;
1673
1674found:
1675        rcu_read_lock();
1676        list_for_each_entry_rcu(opinfo, &lt->lease_list, lease_entry) {
1677                if (!atomic_inc_not_zero(&opinfo->refcount))
1678                        continue;
1679                rcu_read_unlock();
1680                if (!opinfo->op_state || opinfo->op_state == OPLOCK_CLOSING)
1681                        goto op_next;
1682                if (!(opinfo->o_lease->state &
1683                      (SMB2_LEASE_HANDLE_CACHING_LE |
1684                       SMB2_LEASE_WRITE_CACHING_LE)))
1685                        goto op_next;
1686                ret = compare_guid_key(opinfo, conn->ClientGUID,
1687                                       lease_key);
1688                if (ret) {
1689                        ksmbd_debug(OPLOCK, "found opinfo\n");
1690                        ret_op = opinfo;
1691                        goto out;
1692                }
1693op_next:
1694                opinfo_put(opinfo);
1695                rcu_read_lock();
1696        }
1697        rcu_read_unlock();
1698
1699out:
1700        read_unlock(&lease_list_lock);
1701        return ret_op;
1702}
1703
1704int smb2_check_durable_oplock(struct ksmbd_file *fp,
1705                              struct lease_ctx_info *lctx, char *name)
1706{
1707        struct oplock_info *opinfo = opinfo_get(fp);
1708        int ret = 0;
1709
1710        if (opinfo && opinfo->is_lease) {
1711                if (!lctx) {
1712                        pr_err("open does not include lease\n");
1713                        ret = -EBADF;
1714                        goto out;
1715                }
1716                if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
1717                           SMB2_LEASE_KEY_SIZE)) {
1718                        pr_err("invalid lease key\n");
1719                        ret = -EBADF;
1720                        goto out;
1721                }
1722                if (name && strcmp(fp->filename, name)) {
1723                        pr_err("invalid name reconnect %s\n", name);
1724                        ret = -EINVAL;
1725                        goto out;
1726                }
1727        }
1728out:
1729        if (opinfo)
1730                opinfo_put(opinfo);
1731        return ret;
1732}
1733