Skip to content

Commit 0c9dcf1

Browse files
committed
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
2 parents 0dd2a6f + 59a556a commit 0c9dcf1

File tree

4 files changed

+22
-24
lines changed

4 files changed

+22
-24
lines changed

fs/cifs/cifsglob.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,8 @@ struct smb_version_operations {
424424
/* check for STATUS_NETWORK_SESSION_EXPIRED */
425425
bool (*is_session_expired)(char *);
426426
/* send oplock break response */
427-
int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *,
428-
struct cifsInodeInfo *);
427+
int (*oplock_response)(struct cifs_tcon *tcon, __u64 persistent_fid, __u64 volatile_fid,
428+
__u16 net_fid, struct cifsInodeInfo *cifs_inode);
429429
/* query remote filesystem */
430430
int (*queryfs)(const unsigned int, struct cifs_tcon *,
431431
struct cifs_sb_info *, struct kstatfs *);

fs/cifs/file.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4881,9 +4881,9 @@ void cifs_oplock_break(struct work_struct *work)
48814881
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
48824882
struct TCP_Server_Info *server = tcon->ses->server;
48834883
int rc = 0;
4884-
bool purge_cache = false;
4885-
struct cifs_deferred_close *dclose;
4886-
bool is_deferred = false;
4884+
bool purge_cache = false, oplock_break_cancelled;
4885+
__u64 persistent_fid, volatile_fid;
4886+
__u16 net_fid;
48874887

48884888
wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
48894889
TASK_UNINTERRUPTIBLE);
@@ -4924,28 +4924,28 @@ void cifs_oplock_break(struct work_struct *work)
49244924
* file handles but cached, then schedule deferred close immediately.
49254925
* So, new open will not use cached handle.
49264926
*/
4927-
spin_lock(&CIFS_I(inode)->deferred_lock);
4928-
is_deferred = cifs_is_deferred_close(cfile, &dclose);
4929-
spin_unlock(&CIFS_I(inode)->deferred_lock);
49304927

4931-
if (!CIFS_CACHE_HANDLE(cinode) && is_deferred &&
4932-
cfile->deferred_close_scheduled && delayed_work_pending(&cfile->deferred)) {
4928+
if (!CIFS_CACHE_HANDLE(cinode) && !list_empty(&cinode->deferred_closes))
49334929
cifs_close_deferred_file(cinode);
4934-
}
49354930

4931+
persistent_fid = cfile->fid.persistent_fid;
4932+
volatile_fid = cfile->fid.volatile_fid;
4933+
net_fid = cfile->fid.netfid;
4934+
oplock_break_cancelled = cfile->oplock_break_cancelled;
4935+
4936+
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
49364937
/*
49374938
* releasing stale oplock after recent reconnect of smb session using
49384939
* a now incorrect file handle is not a data integrity issue but do
49394940
* not bother sending an oplock release if session to server still is
49404941
* disconnected since oplock already released by the server
49414942
*/
4942-
if (!cfile->oplock_break_cancelled) {
4943-
rc = tcon->ses->server->ops->oplock_response(tcon, &cfile->fid,
4944-
cinode);
4943+
if (!oplock_break_cancelled) {
4944+
rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
4945+
volatile_fid, net_fid, cinode);
49454946
cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
49464947
}
49474948

4948-
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
49494949
cifs_done_oplock_break(cinode);
49504950
}
49514951

fs/cifs/smb1ops.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,11 @@ cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
897897
}
898898

899899
static int
900-
cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
901-
struct cifsInodeInfo *cinode)
900+
cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
901+
__u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cinode)
902902
{
903-
return CIFSSMBLock(0, tcon, fid->netfid, current->tgid, 0, 0, 0, 0,
904-
LOCKING_ANDX_OPLOCK_RELEASE, false,
905-
CIFS_CACHE_READ(cinode) ? 1 : 0);
903+
return CIFSSMBLock(0, tcon, net_fid, current->tgid, 0, 0, 0, 0,
904+
LOCKING_ANDX_OPLOCK_RELEASE, false, CIFS_CACHE_READ(cinode) ? 1 : 0);
906905
}
907906

908907
static int

fs/cifs/smb2ops.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,15 +2383,14 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
23832383
}
23842384

23852385
static int
2386-
smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
2387-
struct cifsInodeInfo *cinode)
2386+
smb2_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
2387+
__u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cinode)
23882388
{
23892389
if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
23902390
return SMB2_lease_break(0, tcon, cinode->lease_key,
23912391
smb2_get_lease_state(cinode));
23922392

2393-
return SMB2_oplock_break(0, tcon, fid->persistent_fid,
2394-
fid->volatile_fid,
2393+
return SMB2_oplock_break(0, tcon, persistent_fid, volatile_fid,
23952394
CIFS_CACHE_READ(cinode) ? 1 : 0);
23962395
}
23972396

0 commit comments

Comments
 (0)