Patch "Handle mismatched open calls" has been added to the 3.18-stable tree
This is a note to let you know that I've just added the patch titled
Handle mismatched open calls
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
handle-mismatched-open-calls.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
38bd49064a1ecb67baad33598e3d824448ab11ecMon Sep 17 00:00:00 2001
From: Sachin Prabhu <[email protected]>
Date: Fri, 3 Mar 2017 15:41:38 -0800
Subject: Handle mismatched open calls
From: Sachin Prabhu <[email protected]>
commit 38bd49064a1ecb67baad33598e3d824448ab11ec upstream.
A signal can interrupt a SendReceive call which result in incoming responses to the call being ignored. This is a problem for calls such as open which results in the successful response being ignored. This results in an open file resource on the server.
The patch looks into responses which were cancelled after being sent and in case of successful open closes the open fids.
For this patch, the check is only done in SendReceive2()
RH-bz: 1403319
--- fs/cifs/cifsglob.h | 11 +++++++++ fs/cifs/cifssmb.c | 4 +++ fs/cifs/connect.c | 13 +++++++++- fs/cifs/smb2misc.c | 44 ++++++++++++++++++++++++++++++++++++ fs/cifs/smb2ops.c | 4 +++ fs/cifs/smb2proto.h | 7 +++++ fs/cifs/smb2transport.c | 58 +++++++++++++++++++++++++++++++++++++++++++----- fs/cifs/transport.c | 2 + 8 files changed, 135 insertions(+), 8 deletions(-)
fs/cifs/cifsglob.h +11 -0
@@ -223,6 +223,7 @@ struct smb_version_operations {/* verify the message */ int (*check_message)(char *,unsigned int );bool (*is_oplock_break)(char *,struct TCP_Server_Info *); +int (*handle_cancelled_mid)(char *,struct TCP_Server_Info *);void (*downgrade_oplock)(struct TCP_Server_Info *,struct cifsInodeInfo *,bool );/* process transaction2 response */
@@ -1264,12 +1265,19 @@ struct mid_q_entry {void *callback_data;/* general purpose pointer for callback */ void *resp_buf;/* pointer to received SMB header */ int mid_state;/* wish this were enum but can not pass to wait_event */ +unsigned int mid_flags;__le16 command;/* smb command code */ bool large_buf:1; /* if valid response, is pointer to large buf */ bool multiRsp:1; /* multiple trans2 responses for one request */ bool multiEnd:1; /* both received */ }; +struct close_cancelled_open { +struct cifs_fid fid; +struct cifs_tcon *tcon; +struct work_struct work; +}; +/* Make code in transport.c a little cleaner by moving update of optional stats into function below */ #ifdef CONFIG_CIFS_STATS2
@@ -1401,6 +1409,9 @@ static inline void free_dfs_info_array(s#define MID_RESPONSE_MALFORMED 0x10#define MID_SHUTDOWN 0x20 +/* Flags */ +#define MID_WAIT_CANCELLED 1/* Cancelled while waiting for response */ +/* Types of response buffer returned from SendReceive2 */ #define CIFS_NO_BUFFER 0/* Response buffer not returned */ #define CIFS_SMALL_BUFFER 1
fs/cifs/cifssmb.c +4 -0
@@ -1422,6 +1422,8 @@ cifs_readv_discard(struct TCP_Server_Inf length =discard_remaining_data (server);dequeue_mid (mid, rdata->result); + mid->resp_buf = server->smallbuf; + server->smallbuf =NULL ;return length; }
@@ -1536,6 +1538,8 @@ cifs_readv_receive(struct TCP_Server_Infreturn cifs_readv_discard (server, mid);dequeue_mid (mid, false); + mid->resp_buf = server->smallbuf; + server->smallbuf =NULL ;return length; }
fs/cifs/connect.c +11 -2
@@ -914,10 +914,19 @@ cifs_demultiplex_thread(void *p) server->lstrp = jiffies;if (mid_entry !=NULL ) { +if ((mid_entry->mid_flags &MID_WAIT_CANCELLED ) && + mid_entry->mid_state ==MID_RESPONSE_RECEIVED && + server->ops->handle_cancelled_mid) + server->ops->handle_cancelled_mid ( + mid_entry->resp_buf, + server); +if (!mid_entry->multiRsp || mid_entry->multiEnd) mid_entry->callback (mid_entry); - }else if (!server->ops->is_oplock_break || - !server->ops->is_oplock_break (buf, server)) { + }else if (server->ops->is_oplock_break && + server->ops->is_oplock_break (buf, server)) { +cifs_dbg (FYI ,"Received oplock break\n" ); + }else {cifs_dbg (VFS ,"No task to wake, unknown frame received! NumMids %d\n" ,atomic_read (&midCount)); cifs_dump_mem("Received Data is: ", buf,
fs/cifs/smb2misc.c +44 -0
47 lines not on this page · raw message
fs/cifs/smb2ops.c +4 -0
@@ -1461,6 +1461,8 @@ struct smb_version_operations smb21_oper .clear_stats = smb2_clear_stats, .print_stats = smb2_print_stats, .is_oplock_break = smb2_is_valid_oplock_break, + .handle_cancelled_mid = smb2_handle_cancelled_mid, + .handle_cancelled_mid = smb2_handle_cancelled_mid, .downgrade_oplock = smb2_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate,
@@ -1542,6 +1544,8 @@ struct smb_version_operations smb30_oper .print_stats = smb2_print_stats, .dump_share_caps = smb2_dump_share_caps, .is_oplock_break = smb2_is_valid_oplock_break, + .handle_cancelled_mid = smb2_handle_cancelled_mid, + .handle_cancelled_mid = smb2_handle_cancelled_mid, .downgrade_oplock = smb2_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate,
fs/cifs/smb2proto.h +7 -0
@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_re struct smb_rqst *rqst);extern struct mid_q_entry *smb2_setup_async_request (struct TCP_Server_Info *server,struct smb_rqst *rqst); +extern struct cifs_ses *smb2_find_smb_ses (struct TCP_Server_Info *server, +__u64 ses_id); +extern struct cifs_tcon *smb2_find_smb_tcon (struct TCP_Server_Info *server, +__u64 ses_id,__u32 tid);extern int smb2_calc_signature (struct smb_rqst *rqst,struct TCP_Server_Info *server); extern int smb3_calc_signature(struct smb_rqst *rqst,
@@ -157,6 +161,9 @@ extern int SMB2_set_compression(const unextern int SMB2_oplock_break (const unsigned int xid,struct cifs_tcon *tcon,const u64 persistent_fid,const u64 volatile_fid,const __u8 oplock_level); +extern int smb2_handle_cancelled_mid (char *buffer, +struct TCP_Server_Info *server); +void smb2_cancelled_close_fid (struct work_struct *work);extern int SMB2_QFS_info (const unsigned int xid,struct cifs_tcon *tcon,u64 persistent_file_id,u64 volatile_file_id,struct kstatfs *FSData);
fs/cifs/smb2transport.c +52 -6
88 lines not on this page · raw message
fs/cifs/transport.c +2 -0
@@ -784,9 +784,11 @@ SendReceive2(const unsigned int xid, str rc =wait_for_response (ses->server, midQ);if (rc !=0 ) { +cifs_dbg (FYI ,"Cancelling wait for mid %llu\n" , midQ->mid);send_cancel (ses->server, buf, midQ);spin_lock (&GlobalMid_Lock);if (midQ->mid_state ==MID_REQUEST_SUBMITTED ) { + midQ->mid_flags |=MID_WAIT_CANCELLED ; midQ->callback = DeleteMidQEntry;spin_unlock (&GlobalMid_Lock);cifs_small_buf_release (buf);
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/handle-mismatched-open-calls.patch