From patchwork Wed Feb 13 23:43:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 10811327 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 47761746 for ; Wed, 13 Feb 2019 23:44:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3609E205FC for ; Wed, 13 Feb 2019 23:44:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2A14E25E97; Wed, 13 Feb 2019 23:44:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B06BE205FC for ; Wed, 13 Feb 2019 23:44:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393150AbfBMXnS (ORCPT ); Wed, 13 Feb 2019 18:43:18 -0500 Received: from mail-pl1-f193.google.com ([209.85.214.193]:43984 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2393102AbfBMXnS (ORCPT ); Wed, 13 Feb 2019 18:43:18 -0500 Received: by mail-pl1-f193.google.com with SMTP id f90so1999907plb.10 for ; Wed, 13 Feb 2019 15:43:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=kHXUtzIRHJyz1moPDbYu6/qRSms020m4qVF9OgsZ1Tg=; b=frLV4UFn/Hl132OOP48K0Z6JHGW0l/304TPisrtCgymvEIl/3H8weyst+oCX7qQonC Y0l200sAQrloH+yRdMk+scgT4bGVggR1EMoxXYlZVh1M4+Gv5Gu2EkrK4MmRj7mMdKzq IgGfXo4z9SRArS0b0jt0wNRhmyFgJu0c29OAnCG4v3b/u6x5KC2BbzztxLMl8cDZp2bY Sh7IjKqGkhNY5mzOSRgsgdtRnpYuCBfnUmvNql7Ta1tgu29b+465shhFnE26LHov5/EX 9Byn7sj4IBZww82U3F9Nmkuk2jnEwcgWfGEPFFE1MtyV4Tw1vobwR3tsPNMMYhVTfMnJ nPJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=kHXUtzIRHJyz1moPDbYu6/qRSms020m4qVF9OgsZ1Tg=; b=S0i5uPdfqTeNyzXlx69GCTckIa4BCP1s3QdzSPMsTxzCWd00DAIcIxjQJAIG0hKxmW /Bxja8P3mdsShBynsceWNvGL1gHp0ZVXPHIaypd3yCzLWZOtZiKcbSo+DPLMwwhiN25F 6EXE8c2BSQuNj/AbViHK3JfKjU1dvCIsbeYYUyhfFUlkD2nqnTuXq48TK+hU66v6/QBu OoqUZC+gxQDI1Yqv2/xWRr10AdujreuN66DSa4Bd3tR44qapR88e/2DzkMkaXFiv4w8v HSpajrplSEk5Fu800RbncrOO/uwf1TUF45H35R7NMGzQfBk1LK6130du0LUfEJXA0U8P Speg== X-Gm-Message-State: AHQUAuaDTm83ADnXoUHaGfSbFosnsA5CXk/AaB9y/CZ8ylyhkClieg5O a3OWR6tsvkLa6iuA4TdYQjYEiYk= X-Google-Smtp-Source: AHgI3IYiV8/X63Rliix41nE6HNarQgKAAkujcT09ll+vlj0CdoDDGWBdihP2VY7RqQzkJFEAQBkExA== X-Received: by 2002:a17:902:e990:: with SMTP id ct16mr818596plb.201.1550101397248; Wed, 13 Feb 2019 15:43:17 -0800 (PST) Received: from ubuntu-vm.corp.microsoft.com ([2001:4898:80e8:b:a183:4e9f:6b7c:507d]) by smtp.gmail.com with ESMTPSA id o1sm549528pgn.63.2019.02.13.15.43.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Feb 2019 15:43:16 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: linux-cifs@vger.kernel.org, smfrench@gmail.com Subject: [PATCH] CIFS: Do not reset lease state to NONE on lease break Date: Wed, 13 Feb 2019 15:43:08 -0800 Message-Id: <1550101388-19431-1-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently on lease break the client sets a caching level twice: when oplock is detected and when oplock is processed. While the 1st attempt sets the level to the value provided by the server, the 2nd one resets the level to None unconditionally. This happens because the oplock/lease processing code was changed to avoid races between page cache flushes and oplock breaks. The commit c11f1df5003d534 ("cifs: Wait for writebacks to complete before attempting write.") fixed the races for oplocks but didn't apply the same changes for leases resulting in overwriting the server granted value to None. Fix this by properly processing lease breaks. Signed-off-by: Pavel Shilovsky --- fs/cifs/smb2misc.c | 17 ++++++++++++++--- fs/cifs/smb2ops.c | 15 ++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index 7b8b58f..58700d2 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -517,7 +517,6 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp, __u8 lease_state; struct list_head *tmp; struct cifsFileInfo *cfile; - struct TCP_Server_Info *server = tcon->ses->server; struct cifs_pending_open *open; struct cifsInodeInfo *cinode; int ack_req = le32_to_cpu(rsp->Flags & @@ -537,13 +536,25 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp, cifs_dbg(FYI, "lease key match, lease break 0x%x\n", le32_to_cpu(rsp->NewLeaseState)); - server->ops->set_oplock_level(cinode, lease_state, 0, NULL); - if (ack_req) cfile->oplock_break_cancelled = false; else cfile->oplock_break_cancelled = true; + set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); + + /* + * Set or clear flags depending on the lease state being READ. + * HANDLE caching flag should be added when the client starts + * to defer closing remote file handles with HANDLE leases. + */ + if (lease_state & SMB2_LEASE_READ_CACHING_HE) + set_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); + else + clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); + queue_work(cifsoplockd_wq, &cfile->oplock_break); kfree(lw); return true; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 1995bbe..e560e60 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2641,6 +2641,15 @@ smb2_downgrade_oplock(struct TCP_Server_Info *server, } static void +smb21_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, bool set_level2) +{ + server->ops->set_oplock_level(cinode, + set_level2 ? SMB2_LEASE_READ_CACHING_HE : + 0, 0, NULL); +} + +static void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, bool *purge_cache) { @@ -3693,7 +3702,7 @@ struct smb_version_operations smb21_operations = { .print_stats = smb2_print_stats, .is_oplock_break = smb2_is_valid_oplock_break, .handle_cancelled_mid = smb2_handle_cancelled_mid, - .downgrade_oplock = smb2_downgrade_oplock, + .downgrade_oplock = smb21_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate, .negotiate_wsize = smb2_negotiate_wsize, @@ -3791,7 +3800,7 @@ struct smb_version_operations smb30_operations = { .dump_share_caps = smb2_dump_share_caps, .is_oplock_break = smb2_is_valid_oplock_break, .handle_cancelled_mid = smb2_handle_cancelled_mid, - .downgrade_oplock = smb2_downgrade_oplock, + .downgrade_oplock = smb21_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate, .negotiate_wsize = smb3_negotiate_wsize, @@ -3897,7 +3906,7 @@ struct smb_version_operations smb311_operations = { .dump_share_caps = smb2_dump_share_caps, .is_oplock_break = smb2_is_valid_oplock_break, .handle_cancelled_mid = smb2_handle_cancelled_mid, - .downgrade_oplock = smb2_downgrade_oplock, + .downgrade_oplock = smb21_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate, .negotiate_wsize = smb3_negotiate_wsize,