lkml.org 
[lkml]   [2019]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 137/280] CIFS: Do not reset lease state to NONE on lease break
    Date
    4.19-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Pavel Shilovsky <piastryyy@gmail.com>

    commit 7b9b9edb49ad377b1e06abf14354c227e9ac4b06 upstream.

    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 <pshilov@microsoft.com>
    Signed-off-by: Steve French <stfrench@microsoft.com>
    CC: Stable <stable@vger.kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/cifs/smb2misc.c | 17 ++++++++++++++---
    fs/cifs/smb2ops.c | 15 ++++++++++++---
    2 files changed, 26 insertions(+), 6 deletions(-)

    --- a/fs/cifs/smb2misc.c
    +++ b/fs/cifs/smb2misc.c
    @@ -517,7 +517,6 @@ smb2_tcon_has_lease(struct cifs_tcon *tc
    __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 *tc
    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;
    --- a/fs/cifs/smb2ops.c
    +++ b/fs/cifs/smb2ops.c
    @@ -2301,6 +2301,15 @@ smb2_downgrade_oplock(struct TCP_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)
    {
    @@ -3351,7 +3360,7 @@ struct smb_version_operations smb21_oper
    .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,
    @@ -3447,7 +3456,7 @@ struct smb_version_operations smb30_oper
    .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 = smb2_negotiate_wsize,
    @@ -3551,7 +3560,7 @@ struct smb_version_operations smb311_ope
    .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 = smb2_negotiate_wsize,

    \
     
     \ /
      Last update: 2019-03-22 13:43    [W:2.114 / U:1.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site