Commit 0c9dcf12 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '6.4-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs client fixes from Steve French:
 "Two smb3 client fixes, both related to deferred close, and also for
  stable:

   - send close for deferred handles before not after lease break
     response to avoid possible sharing violations

   - check all opens on an inode (looking for deferred handles) when
     lease break is returned not just the handle the lease break came in
     on"

* tag '6.4-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  SMB3: drop reference to cfile before sending oplock break
  SMB3: Close all deferred handles of inode in case of handle lease break
parents 0dd2a6fb 59a556ae
...@@ -424,8 +424,8 @@ struct smb_version_operations { ...@@ -424,8 +424,8 @@ struct smb_version_operations {
/* check for STATUS_NETWORK_SESSION_EXPIRED */ /* check for STATUS_NETWORK_SESSION_EXPIRED */
bool (*is_session_expired)(char *); bool (*is_session_expired)(char *);
/* send oplock break response */ /* send oplock break response */
int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, int (*oplock_response)(struct cifs_tcon *tcon, __u64 persistent_fid, __u64 volatile_fid,
struct cifsInodeInfo *); __u16 net_fid, struct cifsInodeInfo *cifs_inode);
/* query remote filesystem */ /* query remote filesystem */
int (*queryfs)(const unsigned int, struct cifs_tcon *, int (*queryfs)(const unsigned int, struct cifs_tcon *,
struct cifs_sb_info *, struct kstatfs *); struct cifs_sb_info *, struct kstatfs *);
......
...@@ -4881,9 +4881,9 @@ void cifs_oplock_break(struct work_struct *work) ...@@ -4881,9 +4881,9 @@ void cifs_oplock_break(struct work_struct *work)
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
struct TCP_Server_Info *server = tcon->ses->server; struct TCP_Server_Info *server = tcon->ses->server;
int rc = 0; int rc = 0;
bool purge_cache = false; bool purge_cache = false, oplock_break_cancelled;
struct cifs_deferred_close *dclose; __u64 persistent_fid, volatile_fid;
bool is_deferred = false; __u16 net_fid;
wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
...@@ -4924,28 +4924,28 @@ void cifs_oplock_break(struct work_struct *work) ...@@ -4924,28 +4924,28 @@ void cifs_oplock_break(struct work_struct *work)
* file handles but cached, then schedule deferred close immediately. * file handles but cached, then schedule deferred close immediately.
* So, new open will not use cached handle. * So, new open will not use cached handle.
*/ */
spin_lock(&CIFS_I(inode)->deferred_lock);
is_deferred = cifs_is_deferred_close(cfile, &dclose);
spin_unlock(&CIFS_I(inode)->deferred_lock);
if (!CIFS_CACHE_HANDLE(cinode) && is_deferred && if (!CIFS_CACHE_HANDLE(cinode) && !list_empty(&cinode->deferred_closes))
cfile->deferred_close_scheduled && delayed_work_pending(&cfile->deferred)) {
cifs_close_deferred_file(cinode); cifs_close_deferred_file(cinode);
}
persistent_fid = cfile->fid.persistent_fid;
volatile_fid = cfile->fid.volatile_fid;
net_fid = cfile->fid.netfid;
oplock_break_cancelled = cfile->oplock_break_cancelled;
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
/* /*
* releasing stale oplock after recent reconnect of smb session using * releasing stale oplock after recent reconnect of smb session using
* a now incorrect file handle is not a data integrity issue but do * a now incorrect file handle is not a data integrity issue but do
* not bother sending an oplock release if session to server still is * not bother sending an oplock release if session to server still is
* disconnected since oplock already released by the server * disconnected since oplock already released by the server
*/ */
if (!cfile->oplock_break_cancelled) { if (!oplock_break_cancelled) {
rc = tcon->ses->server->ops->oplock_response(tcon, &cfile->fid, rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
cinode); volatile_fid, net_fid, cinode);
cifs_dbg(FYI, "Oplock release rc = %d\n", rc); cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
} }
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
cifs_done_oplock_break(cinode); cifs_done_oplock_break(cinode);
} }
......
...@@ -897,12 +897,11 @@ cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -897,12 +897,11 @@ cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
} }
static int static int
cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
struct cifsInodeInfo *cinode) __u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cinode)
{ {
return CIFSSMBLock(0, tcon, fid->netfid, current->tgid, 0, 0, 0, 0, return CIFSSMBLock(0, tcon, net_fid, current->tgid, 0, 0, 0, 0,
LOCKING_ANDX_OPLOCK_RELEASE, false, LOCKING_ANDX_OPLOCK_RELEASE, false, CIFS_CACHE_READ(cinode) ? 1 : 0);
CIFS_CACHE_READ(cinode) ? 1 : 0);
} }
static int static int
......
...@@ -2383,15 +2383,14 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server) ...@@ -2383,15 +2383,14 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
} }
static int static int
smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, smb2_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
struct cifsInodeInfo *cinode) __u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cinode)
{ {
if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
return SMB2_lease_break(0, tcon, cinode->lease_key, return SMB2_lease_break(0, tcon, cinode->lease_key,
smb2_get_lease_state(cinode)); smb2_get_lease_state(cinode));
return SMB2_oplock_break(0, tcon, fid->persistent_fid, return SMB2_oplock_break(0, tcon, persistent_fid, volatile_fid,
fid->volatile_fid,
CIFS_CACHE_READ(cinode) ? 1 : 0); CIFS_CACHE_READ(cinode) ? 1 : 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment