FAILED: patch "[PATCH] cifs: do not send close in compound create+close requests" failed to apply to 5.4-stable tree
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 04ad69c342fc4de5bd23be9ef15ea7574fb1a87e Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <[email protected]>
Date: Mon, 8 Mar 2021 12:00:50 -0300
Subject: [PATCH] cifs: do not send close in compound create+close requests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case of interrupted syscalls, prevent sending CLOSE commands for compound CREATE+CLOSE requests by introducing an CIFS_CP_CREATE_CLOSE_OP flag to indicate lower layers that it should not send a CLOSE command to the MIDs corresponding the compound CREATE+CLOSE request.
A simple reproducer:
#!/bin/bash
mount //server/share /mnt -o username=foo,password=*** tc qdisc add dev eth0 root netem delay 450ms stat -f /mnt &>/dev/null & pid=$!
sleep 0.01
kill $pid
tc qdisc del dev eth0 root
umount /mnt
Before patch:
...
6 0.256893470 192.168.122.2 → 192.168.122.15 SMB2 402 Create Request File: ;GetInfo Request FS_INFO/FileFsFullSizeInformation;Close Request
7 0.257144491 192.168.122.15 → 192.168.122.2 SMB2 498 Create Response File: ;GetInfo Response;Close Response
9 0.260798209 192.168.122.2 → 192.168.122.15 SMB2 146 Close Request File: 10 0.260841089 192.168.122.15 → 192.168.122.2 SMB2 130 Close Response, Error: STATUS_FILE_CLOSED
fs/cifs/cifsglob.h +10 -9
@@ -257,7 +257,7 @@ struct smb_version_operations {/* verify the message */ int (*check_message)(char *,unsigned int ,struct TCP_Server_Info *);bool (*is_oplock_break)(char *,struct TCP_Server_Info *); -int (*handle_cancelled_mid)(char *,struct TCP_Server_Info *); +int (*handle_cancelled_mid)(struct mid_q_entry *,struct TCP_Server_Info *);void (*downgrade_oplock)(struct TCP_Server_Info *server,struct cifsInodeInfo *cinode,__u32 oplock,unsigned int epoch,bool *purge_cache);
@@ -1705,16 +1705,17 @@ static inline bool is_retryable_error(int error)#define CIFS_NO_RSP_BUF 0x040/* no response buffer required */ /* Type of request operation */ -#define CIFS_ECHO_OP 0x080/* echo request */ -#define CIFS_OBREAK_OP 0x0100/* oplock break request */ -#define CIFS_NEG_OP 0x0200/* negotiate request */ +#define CIFS_ECHO_OP 0x080/* echo request */ +#define CIFS_OBREAK_OP 0x0100/* oplock break request */ +#define CIFS_NEG_OP 0x0200/* negotiate request */ +#define CIFS_CP_CREATE_CLOSE_OP 0x0400/* compound create+close request */ /* Lower bitmask values are reserved by others below. */ -#define CIFS_SESS_OP 0x2000/* session setup request */ -#define CIFS_OP_MASK 0x2380/* mask request type */ +#define CIFS_SESS_OP 0x2000/* session setup request */ +#define CIFS_OP_MASK 0x2780/* mask request type */ -#define CIFS_HAS_CREDITS 0x0400/* already has credits */ -#define CIFS_TRANSFORM_REQ 0x0800/* transform request before sending */ -#define CIFS_NO_SRV_RSP 0x1000/* there is no server response */ +#define CIFS_HAS_CREDITS 0x0400/* already has credits */ +#define CIFS_TRANSFORM_REQ 0x0800/* transform request before sending */ +#define CIFS_NO_SRV_RSP 0x1000/* there is no server response */ /* Security Flags: indicate type of session setup needed */ #define CIFSSEC_MAY_SIGN 0x00001
fs/cifs/smb2inode.c +1 -0
@@ -358,6 +358,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,if (cfile) goto after_close;/* Close */ + flags |=CIFS_CP_CREATE_CLOSE_OP ; rqst[num_rqst].rq_iov = &vars->close_iov[0 ]; rqst[num_rqst].rq_nvec =1 ; rc = SMB2_close_init(tcon, server,
fs/cifs/smb2misc.c +4 -4
@@ -844,14 +844,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, }int -smb2_handle_cancelled_mid (char *buffer,struct TCP_Server_Info *server) +smb2_handle_cancelled_mid (struct mid_q_entry *mid,struct TCP_Server_Info *server) { -struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer; -struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; +struct smb2_sync_hdr *sync_hdr = mid->resp_buf; +struct smb2_create_rsp *rsp = mid->resp_buf;struct cifs_tcon *tcon;int rc; -if (sync_hdr->Command !=SMB2_CREATE || +if ((mid->optype &CIFS_CP_CREATE_CLOSE_OP ) || sync_hdr->Command !=SMB2_CREATE || sync_hdr->Status !=STATUS_SUCCESS )return 0 ;
fs/cifs/smb2ops.c +5 -5
@@ -1195,7 +1195,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,struct TCP_Server_Info *server =cifs_pick_channel (ses);__le16 *utf16_path =NULL ;int ea_name_len =strlen (ea_name); -int flags =0 ; +int flags =CIFS_CP_CREATE_CLOSE_OP ;int len;struct smb_rqst rqst[3 ];int resp_buftype[3 ];
@@ -1573,7 +1573,7 @@ smb2_ioctl_query_info(const unsigned int xid,struct smb_query_info qi;struct smb_query_info __user *pqi;int rc =0 ; -int flags =0 ; +int flags =CIFS_CP_CREATE_CLOSE_OP ;struct smb2_query_info_rsp *qi_rsp =NULL ;struct smb2_ioctl_rsp *io_rsp =NULL ;void *buffer =NULL ;
@@ -2577,7 +2577,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, {struct cifs_ses *ses = tcon->ses;struct TCP_Server_Info *server =cifs_pick_channel (ses); -int flags =0 ; +int flags =CIFS_CP_CREATE_CLOSE_OP ;struct smb_rqst rqst[3 ];int resp_buftype[3 ];struct kvec rsp_iov[3 ];
@@ -2975,7 +2975,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,unsigned int sub_offset;unsigned int print_len;unsigned int print_offset; -int flags =0 ; +int flags =CIFS_CP_CREATE_CLOSE_OP ;struct smb_rqst rqst[3 ];int resp_buftype[3 ];struct kvec rsp_iov[3 ];
@@ -3157,7 +3157,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,struct cifs_open_parms oparms;struct cifs_fid fid;struct TCP_Server_Info *server =cifs_pick_channel (tcon->ses); -int flags =0 ; +int flags =CIFS_CP_CREATE_CLOSE_OP ;struct smb_rqst rqst[3 ];int resp_buftype[3 ];struct kvec rsp_iov[3 ];
fs/cifs/smb2proto.h +1 -2
@@ -246,8 +246,7 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,extern int smb2_handle_cancelled_close (struct cifs_tcon *tcon,__u64 persistent_fid,__u64 volatile_fid); -extern int smb2_handle_cancelled_mid (char *buffer, -struct TCP_Server_Info *server); +extern int smb2_handle_cancelled_mid (struct mid_q_entry *mid,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,
fs/cifs/transport.c +1 -1
@@ -101,7 +101,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount)if (midEntry->resp_buf && (midEntry->mid_flags &MID_WAIT_CANCELLED ) && midEntry->mid_state ==MID_RESPONSE_RECEIVED && server->ops->handle_cancelled_mid) - server->ops->handle_cancelled_mid (midEntry->resp_buf, server); + server->ops->handle_cancelled_mid (midEntry, server); midEntry->mid_state =MID_FREE ;atomic_dec (&midCount);