Skip to content

Commit

Permalink
CIFS: Do not reset lease state to NONE on lease break
Browse files Browse the repository at this point in the history
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 c11f1df ("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 <[email protected]>
Signed-off-by: Steve French <[email protected]>
CC: Stable <[email protected]>
  • Loading branch information
piastry authored and Steve French committed Mar 5, 2019
1 parent d26e290 commit 7b9b9ed
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
17 changes: 14 additions & 3 deletions fs/cifs/smb2misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &
Expand All @@ -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;
Expand Down
15 changes: 12 additions & 3 deletions fs/cifs/smb2ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -2604,6 +2604,15 @@ smb2_downgrade_oplock(struct TCP_Server_Info *server,
server->ops->set_oplock_level(cinode, 0, 0, NULL);
}

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)
Expand Down Expand Up @@ -3656,7 +3665,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,
Expand Down Expand Up @@ -3753,7 +3762,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,
Expand Down Expand Up @@ -3858,7 +3867,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,
Expand Down

0 comments on commit 7b9b9ed

Please sign in to comment.