aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-09 14:48:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-09 14:48:20 -0500
commite519a8c2c3431fbc27e453ff73f5b51df5afe6b5 (patch)
tree369681ad5b22aaa99e9fa56acbe10b23bef19735
parentd1cae94871330cb9f5fdcea34529abf7917e682e (diff)
parent50cfad780bcf9e03d11aaf0a7296a4c0ed336b54 (diff)
Merge tag '5.1-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull smb3 updates from Steve French: - smb3/cifs fixes including for large i/o error cases - fixes for three xfstests - improved crediting (smb3 flow control) - improved tracing * tag '5.1-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: (44 commits) fs: cifs: Kconfig: pedantic formatting smb3: request more credits on normal (non-large read/write) ops CIFS: Mask off signals when sending SMB packets CIFS: Return -EAGAIN instead of -ENOTSOCK CIFS: Only send SMB2_NEGOTIATE command on new TCP connections CIFS: Fix read after write for files with read caching smb3: for kerberos mounts display the credential uid used cifs: use correct format characters smb3: add dynamic trace point for query_info_enter/done smb3: add dynamic trace point for smb3_cmd_enter smb3: improve dynamic tracing of open and posix mkdir smb3: add missing read completion trace point smb3: Add tracepoints for read, write and query_dir enter smb3: add tracepoints for query dir smb3: Update POSIX negotiate context with POSIX ctxt GUID cifs: update internal module version number CIFS: Try to acquire credits at once for compound requests CIFS: Return error code when getting file handle for writeback CIFS: Move open file handling to writepages CIFS: Move unlocking pages from wdata_send_pages() ...
-rw-r--r--fs/cifs/Kconfig120
-rw-r--r--fs/cifs/cifs_dfs_ref.c4
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c3
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h65
-rw-r--r--fs/cifs/cifsproto.h8
-rw-r--r--fs/cifs/cifssmb.c54
-rw-r--r--fs/cifs/connect.c66
-rw-r--r--fs/cifs/file.c269
-rw-r--r--fs/cifs/inode.c2
-rw-r--r--fs/cifs/link.c14
-rw-r--r--fs/cifs/smb1ops.c8
-rw-r--r--fs/cifs/smb2misc.c24
-rw-r--r--fs/cifs/smb2ops.c115
-rw-r--r--fs/cifs/smb2pdu.c179
-rw-r--r--fs/cifs/smb2pdu.h4
-rw-r--r--fs/cifs/smb2transport.c25
-rw-r--r--fs/cifs/smbdirect.c6
-rw-r--r--fs/cifs/trace.h89
-rw-r--r--fs/cifs/transport.c208
21 files changed, 929 insertions, 337 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index f1ddc9d03c10..76724efc831c 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -117,25 +117,25 @@ config CIFS_UPCALL
117 secure Kerberos authentication is required). If unsure, say Y. 117 secure Kerberos authentication is required). If unsure, say Y.
118 118
119config CIFS_XATTR 119config CIFS_XATTR
120 bool "CIFS extended attributes" 120 bool "CIFS extended attributes"
121 depends on CIFS 121 depends on CIFS
122 help 122 help
123 Extended attributes are name:value pairs associated with inodes by 123 Extended attributes are name:value pairs associated with inodes by
124 the kernel or by users (see the attr(5) manual page for details). 124 the kernel or by users (see the attr(5) manual page for details).
125 CIFS maps the name of extended attributes beginning with the user 125 CIFS maps the name of extended attributes beginning with the user
126 namespace prefix to SMB/CIFS EAs. EAs are stored on Windows 126 namespace prefix to SMB/CIFS EAs. EAs are stored on Windows
127 servers without the user namespace prefix, but their names are 127 servers without the user namespace prefix, but their names are
128 seen by Linux cifs clients prefaced by the user namespace prefix. 128 seen by Linux cifs clients prefaced by the user namespace prefix.
129 The system namespace (used by some filesystems to store ACLs) is 129 The system namespace (used by some filesystems to store ACLs) is
130 not supported at this time. 130 not supported at this time.
131 131
132 If unsure, say Y. 132 If unsure, say Y.
133 133
134config CIFS_POSIX 134config CIFS_POSIX
135 bool "CIFS POSIX Extensions" 135 bool "CIFS POSIX Extensions"
136 depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY && CIFS_XATTR 136 depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY && CIFS_XATTR
137 help 137 help
138 Enabling this option will cause the cifs client to attempt to 138 Enabling this option will cause the cifs client to attempt to
139 negotiate a newer dialect with servers, such as Samba 3.0.5 139 negotiate a newer dialect with servers, such as Samba 3.0.5
140 or later, that optionally can handle more POSIX like (rather 140 or later, that optionally can handle more POSIX like (rather
141 than Windows like) file behavior. It also enables 141 than Windows like) file behavior. It also enables
@@ -144,61 +144,62 @@ config CIFS_POSIX
144 CIFS POSIX ACL support. If unsure, say N. 144 CIFS POSIX ACL support. If unsure, say N.
145 145
146config CIFS_ACL 146config CIFS_ACL
147 bool "Provide CIFS ACL support" 147 bool "Provide CIFS ACL support"
148 depends on CIFS_XATTR && KEYS 148 depends on CIFS_XATTR && KEYS
149 help 149 help
150 Allows fetching CIFS/NTFS ACL from the server. The DACL blob 150 Allows fetching CIFS/NTFS ACL from the server. The DACL blob
151 is handed over to the application/caller. See the man 151 is handed over to the application/caller. See the man
152 page for getcifsacl for more information. If unsure, say Y. 152 page for getcifsacl for more information. If unsure, say Y.
153 153
154config CIFS_DEBUG 154config CIFS_DEBUG
155 bool "Enable CIFS debugging routines" 155 bool "Enable CIFS debugging routines"
156 default y 156 default y
157 depends on CIFS 157 depends on CIFS
158 help 158 help
159 Enabling this option adds helpful debugging messages to 159 Enabling this option adds helpful debugging messages to
160 the cifs code which increases the size of the cifs module. 160 the cifs code which increases the size of the cifs module.
161 If unsure, say Y. 161 If unsure, say Y.
162
162config CIFS_DEBUG2 163config CIFS_DEBUG2
163 bool "Enable additional CIFS debugging routines" 164 bool "Enable additional CIFS debugging routines"
164 depends on CIFS_DEBUG 165 depends on CIFS_DEBUG
165 help 166 help
166 Enabling this option adds a few more debugging routines 167 Enabling this option adds a few more debugging routines
167 to the cifs code which slightly increases the size of 168 to the cifs code which slightly increases the size of
168 the cifs module and can cause additional logging of debug 169 the cifs module and can cause additional logging of debug
169 messages in some error paths, slowing performance. This 170 messages in some error paths, slowing performance. This
170 option can be turned off unless you are debugging 171 option can be turned off unless you are debugging
171 cifs problems. If unsure, say N. 172 cifs problems. If unsure, say N.
172 173
173config CIFS_DEBUG_DUMP_KEYS 174config CIFS_DEBUG_DUMP_KEYS
174 bool "Dump encryption keys for offline decryption (Unsafe)" 175 bool "Dump encryption keys for offline decryption (Unsafe)"
175 depends on CIFS_DEBUG 176 depends on CIFS_DEBUG
176 help 177 help
177 Enabling this will dump the encryption and decryption keys 178 Enabling this will dump the encryption and decryption keys
178 used to communicate on an encrypted share connection on the 179 used to communicate on an encrypted share connection on the
179 console. This allows Wireshark to decrypt and dissect 180 console. This allows Wireshark to decrypt and dissect
180 encrypted network captures. Enable this carefully. 181 encrypted network captures. Enable this carefully.
181 If unsure, say N. 182 If unsure, say N.
182 183
183config CIFS_DFS_UPCALL 184config CIFS_DFS_UPCALL
184 bool "DFS feature support" 185 bool "DFS feature support"
185 depends on CIFS && KEYS 186 depends on CIFS && KEYS
186 select DNS_RESOLVER 187 select DNS_RESOLVER
187 help 188 help
188 Distributed File System (DFS) support is used to access shares 189 Distributed File System (DFS) support is used to access shares
189 transparently in an enterprise name space, even if the share 190 transparently in an enterprise name space, even if the share
190 moves to a different server. This feature also enables 191 moves to a different server. This feature also enables
191 an upcall mechanism for CIFS which contacts userspace helper 192 an upcall mechanism for CIFS which contacts userspace helper
192 utilities to provide server name resolution (host names to 193 utilities to provide server name resolution (host names to
193 IP addresses) which is needed in order to reconnect to 194 IP addresses) which is needed in order to reconnect to
194 servers if their addresses change or for implicit mounts of 195 servers if their addresses change or for implicit mounts of
195 DFS junction points. If unsure, say Y. 196 DFS junction points. If unsure, say Y.
196 197
197config CIFS_NFSD_EXPORT 198config CIFS_NFSD_EXPORT
198 bool "Allow nfsd to export CIFS file system" 199 bool "Allow nfsd to export CIFS file system"
199 depends on CIFS && BROKEN 200 depends on CIFS && BROKEN
200 help 201 help
201 Allows NFS server to export a CIFS mounted share (nfsd over cifs) 202 Allows NFS server to export a CIFS mounted share (nfsd over cifs)
202 203
203config CIFS_SMB_DIRECT 204config CIFS_SMB_DIRECT
204 bool "SMB Direct support (Experimental)" 205 bool "SMB Direct support (Experimental)"
@@ -209,10 +210,9 @@ config CIFS_SMB_DIRECT
209 say N. 210 say N.
210 211
211config CIFS_FSCACHE 212config CIFS_FSCACHE
212 bool "Provide CIFS client caching support" 213 bool "Provide CIFS client caching support"
213 depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y 214 depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
214 help 215 help
215 Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data 216 Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
216 to be cached locally on disk through the general filesystem cache 217 to be cached locally on disk through the general filesystem cache
217 manager. If unsure, say N. 218 manager. If unsure, say N.
218
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index d9b99abe1243..5d83c924cc47 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -285,9 +285,9 @@ static void dump_referral(const struct dfs_info3_param *ref)
285{ 285{
286 cifs_dbg(FYI, "DFS: ref path: %s\n", ref->path_name); 286 cifs_dbg(FYI, "DFS: ref path: %s\n", ref->path_name);
287 cifs_dbg(FYI, "DFS: node path: %s\n", ref->node_name); 287 cifs_dbg(FYI, "DFS: node path: %s\n", ref->node_name);
288 cifs_dbg(FYI, "DFS: fl: %hd, srv_type: %hd\n", 288 cifs_dbg(FYI, "DFS: fl: %d, srv_type: %d\n",
289 ref->flags, ref->server_type); 289 ref->flags, ref->server_type);
290 cifs_dbg(FYI, "DFS: ref_flags: %hd, path_consumed: %hd\n", 290 cifs_dbg(FYI, "DFS: ref_flags: %d, path_consumed: %d\n",
291 ref->ref_flag, ref->path_consumed); 291 ref->ref_flag, ref->path_consumed);
292} 292}
293 293
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 42f0d67f1054..ed49222abecb 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -58,6 +58,7 @@ struct cifs_sb_info {
58 spinlock_t tlink_tree_lock; 58 spinlock_t tlink_tree_lock;
59 struct tcon_link *master_tlink; 59 struct tcon_link *master_tlink;
60 struct nls_table *local_nls; 60 struct nls_table *local_nls;
61 unsigned int bsize;
61 unsigned int rsize; 62 unsigned int rsize;
62 unsigned int wsize; 63 unsigned int wsize;
63 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 64 unsigned long actimeo; /* attribute cache timeout (jiffies) */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 62d48d486d8f..217276b8b942 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -381,7 +381,7 @@ cifs_show_security(struct seq_file *s, struct cifs_ses *ses)
381 seq_puts(s, "ntlm"); 381 seq_puts(s, "ntlm");
382 break; 382 break;
383 case Kerberos: 383 case Kerberos:
384 seq_puts(s, "krb5"); 384 seq_printf(s, "krb5,cruid=%u", from_kuid_munged(&init_user_ns,ses->cred_uid));
385 break; 385 break;
386 case RawNTLMSSP: 386 case RawNTLMSSP:
387 seq_puts(s, "ntlmssp"); 387 seq_puts(s, "ntlmssp");
@@ -554,6 +554,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
554 554
555 seq_printf(s, ",rsize=%u", cifs_sb->rsize); 555 seq_printf(s, ",rsize=%u", cifs_sb->rsize);
556 seq_printf(s, ",wsize=%u", cifs_sb->wsize); 556 seq_printf(s, ",wsize=%u", cifs_sb->wsize);
557 seq_printf(s, ",bsize=%u", cifs_sb->bsize);
557 seq_printf(s, ",echo_interval=%lu", 558 seq_printf(s, ",echo_interval=%lu",
558 tcon->ses->server->echo_interval / HZ); 559 tcon->ses->server->echo_interval / HZ);
559 if (tcon->snapshot_time) 560 if (tcon->snapshot_time)
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 7652551a1fc4..142164ef1f05 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -150,5 +150,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
150extern const struct export_operations cifs_export_ops; 150extern const struct export_operations cifs_export_ops;
151#endif /* CONFIG_CIFS_NFSD_EXPORT */ 151#endif /* CONFIG_CIFS_NFSD_EXPORT */
152 152
153#define CIFS_VERSION "2.17" 153#define CIFS_VERSION "2.18"
154#endif /* _CIFSFS_H */ 154#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 94dbdbe5be34..f293e052e351 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -216,6 +216,7 @@ struct cifs_io_parms;
216struct cifs_search_info; 216struct cifs_search_info;
217struct cifsInodeInfo; 217struct cifsInodeInfo;
218struct cifs_open_parms; 218struct cifs_open_parms;
219struct cifs_credits;
219 220
220struct smb_version_operations { 221struct smb_version_operations {
221 int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *, 222 int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *,
@@ -230,12 +231,15 @@ struct smb_version_operations {
230 /* check response: verify signature, map error */ 231 /* check response: verify signature, map error */
231 int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, 232 int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
232 bool); 233 bool);
233 void (*add_credits)(struct TCP_Server_Info *, const unsigned int, 234 void (*add_credits)(struct TCP_Server_Info *server,
234 const int); 235 const struct cifs_credits *credits,
236 const int optype);
235 void (*set_credits)(struct TCP_Server_Info *, const int); 237 void (*set_credits)(struct TCP_Server_Info *, const int);
236 int * (*get_credits_field)(struct TCP_Server_Info *, const int); 238 int * (*get_credits_field)(struct TCP_Server_Info *, const int);
237 unsigned int (*get_credits)(struct mid_q_entry *); 239 unsigned int (*get_credits)(struct mid_q_entry *);
238 __u64 (*get_next_mid)(struct TCP_Server_Info *); 240 __u64 (*get_next_mid)(struct TCP_Server_Info *);
241 void (*revert_current_mid)(struct TCP_Server_Info *server,
242 const unsigned int val);
239 /* data offset from read response message */ 243 /* data offset from read response message */
240 unsigned int (*read_data_offset)(char *); 244 unsigned int (*read_data_offset)(char *);
241 /* 245 /*
@@ -383,8 +387,8 @@ struct smb_version_operations {
383 struct cifs_fid *); 387 struct cifs_fid *);
384 /* calculate a size of SMB message */ 388 /* calculate a size of SMB message */
385 unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi); 389 unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi);
386 /* check for STATUS_PENDING and process it in a positive case */ 390 /* check for STATUS_PENDING and process the response if yes */
387 bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); 391 bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server);
388 /* check for STATUS_NETWORK_SESSION_EXPIRED */ 392 /* check for STATUS_NETWORK_SESSION_EXPIRED */
389 bool (*is_session_expired)(char *); 393 bool (*is_session_expired)(char *);
390 /* send oplock break response */ 394 /* send oplock break response */
@@ -452,7 +456,11 @@ struct smb_version_operations {
452 unsigned int (*wp_retry_size)(struct inode *); 456 unsigned int (*wp_retry_size)(struct inode *);
453 /* get mtu credits */ 457 /* get mtu credits */
454 int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, 458 int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int,
455 unsigned int *, unsigned int *); 459 unsigned int *, struct cifs_credits *);
460 /* adjust previously taken mtu credits to request size */
461 int (*adjust_credits)(struct TCP_Server_Info *server,
462 struct cifs_credits *credits,
463 const unsigned int payload_size);
456 /* check if we need to issue closedir */ 464 /* check if we need to issue closedir */
457 bool (*dir_needs_close)(struct cifsFileInfo *); 465 bool (*dir_needs_close)(struct cifsFileInfo *);
458 long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, 466 long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
@@ -557,6 +565,7 @@ struct smb_vol {
557 bool resilient:1; /* noresilient not required since not fored for CA */ 565 bool resilient:1; /* noresilient not required since not fored for CA */
558 bool domainauto:1; 566 bool domainauto:1;
559 bool rdma:1; 567 bool rdma:1;
568 unsigned int bsize;
560 unsigned int rsize; 569 unsigned int rsize;
561 unsigned int wsize; 570 unsigned int wsize;
562 bool sockopt_tcp_nodelay:1; 571 bool sockopt_tcp_nodelay:1;
@@ -710,6 +719,11 @@ struct TCP_Server_Info {
710 int nr_targets; 719 int nr_targets;
711}; 720};
712 721
722struct cifs_credits {
723 unsigned int value;
724 unsigned int instance;
725};
726
713static inline unsigned int 727static inline unsigned int
714in_flight(struct TCP_Server_Info *server) 728in_flight(struct TCP_Server_Info *server)
715{ 729{
@@ -731,18 +745,18 @@ has_credits(struct TCP_Server_Info *server, int *credits)
731} 745}
732 746
733static inline void 747static inline void
734add_credits(struct TCP_Server_Info *server, const unsigned int add, 748add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
735 const int optype) 749 const int optype)
736{ 750{
737 server->ops->add_credits(server, add, optype); 751 server->ops->add_credits(server, credits, optype);
738} 752}
739 753
740static inline void 754static inline void
741add_credits_and_wake_if(struct TCP_Server_Info *server, const unsigned int add, 755add_credits_and_wake_if(struct TCP_Server_Info *server,
742 const int optype) 756 const struct cifs_credits *credits, const int optype)
743{ 757{
744 if (add) { 758 if (credits->value) {
745 server->ops->add_credits(server, add, optype); 759 server->ops->add_credits(server, credits, optype);
746 wake_up(&server->request_q); 760 wake_up(&server->request_q);
747 } 761 }
748} 762}
@@ -753,6 +767,14 @@ set_credits(struct TCP_Server_Info *server, const int val)
753 server->ops->set_credits(server, val); 767 server->ops->set_credits(server, val);
754} 768}
755 769
770static inline int
771adjust_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
772 const unsigned int payload_size)
773{
774 return server->ops->adjust_credits ?
775 server->ops->adjust_credits(server, credits, payload_size) : 0;
776}
777
756static inline __le64 778static inline __le64
757get_next_mid64(struct TCP_Server_Info *server) 779get_next_mid64(struct TCP_Server_Info *server)
758{ 780{
@@ -770,6 +792,22 @@ get_next_mid(struct TCP_Server_Info *server)
770 return cpu_to_le16(mid); 792 return cpu_to_le16(mid);
771} 793}
772 794
795static inline void
796revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
797{
798 if (server->ops->revert_current_mid)
799 server->ops->revert_current_mid(server, val);
800}
801
802static inline void
803revert_current_mid_from_hdr(struct TCP_Server_Info *server,
804 const struct smb2_sync_hdr *shdr)
805{
806 unsigned int num = le16_to_cpu(shdr->CreditCharge);
807
808 return revert_current_mid(server, num > 0 ? num : 1);
809}
810
773static inline __u16 811static inline __u16
774get_mid(const struct smb_hdr *smb) 812get_mid(const struct smb_hdr *smb)
775{ 813{
@@ -1234,7 +1272,7 @@ struct cifs_readdata {
1234 unsigned int pagesz; 1272 unsigned int pagesz;
1235 unsigned int page_offset; 1273 unsigned int page_offset;
1236 unsigned int tailsz; 1274 unsigned int tailsz;
1237 unsigned int credits; 1275 struct cifs_credits credits;
1238 unsigned int nr_pages; 1276 unsigned int nr_pages;
1239 struct page **pages; 1277 struct page **pages;
1240}; 1278};
@@ -1260,7 +1298,7 @@ struct cifs_writedata {
1260 unsigned int pagesz; 1298 unsigned int pagesz;
1261 unsigned int page_offset; 1299 unsigned int page_offset;
1262 unsigned int tailsz; 1300 unsigned int tailsz;
1263 unsigned int credits; 1301 struct cifs_credits credits;
1264 unsigned int nr_pages; 1302 unsigned int nr_pages;
1265 struct page **pages; 1303 struct page **pages;
1266}; 1304};
@@ -1422,6 +1460,7 @@ struct mid_q_entry {
1422 struct kref refcount; 1460 struct kref refcount;
1423 struct TCP_Server_Info *server; /* server corresponding to this mid */ 1461 struct TCP_Server_Info *server; /* server corresponding to this mid */
1424 __u64 mid; /* multiplex id */ 1462 __u64 mid; /* multiplex id */
1463 __u16 credits; /* number of credits consumed by this mid */
1425 __u32 pid; /* process id */ 1464 __u32 pid; /* process id */
1426 __u32 sequence_number; /* for CIFS signing */ 1465 __u32 sequence_number; /* for CIFS signing */
1427 unsigned long when_alloc; /* when mid was created */ 1466 unsigned long when_alloc; /* when mid was created */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 336c116995d7..4f96b3b00a7a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -93,7 +93,8 @@ extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
93extern int cifs_call_async(struct TCP_Server_Info *server, 93extern int cifs_call_async(struct TCP_Server_Info *server,
94 struct smb_rqst *rqst, 94 struct smb_rqst *rqst,
95 mid_receive_t *receive, mid_callback_t *callback, 95 mid_receive_t *receive, mid_callback_t *callback,
96 mid_handle_t *handle, void *cbdata, const int flags); 96 mid_handle_t *handle, void *cbdata, const int flags,
97 const struct cifs_credits *exist_credits);
97extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, 98extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
98 struct smb_rqst *rqst, int *resp_buf_type, 99 struct smb_rqst *rqst, int *resp_buf_type,
99 const int flags, struct kvec *resp_iov); 100 const int flags, struct kvec *resp_iov);
@@ -115,7 +116,7 @@ extern int cifs_check_receive(struct mid_q_entry *mid,
115 struct TCP_Server_Info *server, bool log_error); 116 struct TCP_Server_Info *server, bool log_error);
116extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server, 117extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server,
117 unsigned int size, unsigned int *num, 118 unsigned int size, unsigned int *num,
118 unsigned int *credits); 119 struct cifs_credits *credits);
119extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, 120extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
120 struct kvec *, int /* nvec to send */, 121 struct kvec *, int /* nvec to send */,
121 int * /* type of buf returned */, const int flags, 122 int * /* type of buf returned */, const int flags,
@@ -133,6 +134,9 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
133extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 134extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
134 unsigned int bytes_written); 135 unsigned int bytes_written);
135extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); 136extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
137extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
138 bool fsuid_only,
139 struct cifsFileInfo **ret_file);
136extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 140extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
137extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server); 141extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
138extern int decode_negTokenInit(unsigned char *security_blob, int length, 142extern int decode_negTokenInit(unsigned char *security_blob, int length,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index bb54ccf8481c..f43747c062a7 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -139,8 +139,8 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
139 return -ENOMEM; 139 return -ENOMEM;
140 140
141 if (tcon->ipc) { 141 if (tcon->ipc) {
142 snprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", 142 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
143 tcon->ses->server->hostname); 143 tcon->ses->server->hostname);
144 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc); 144 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
145 goto out; 145 goto out;
146 } 146 }
@@ -172,7 +172,7 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
172 continue; 172 continue;
173 } 173 }
174 174
175 snprintf(tree, MAX_TREE_SIZE, "\\%s", tgt); 175 scnprintf(tree, MAX_TREE_SIZE, "\\%s", tgt);
176 176
177 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc); 177 rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
178 if (!rc) 178 if (!rc)
@@ -822,9 +822,10 @@ static void
822cifs_echo_callback(struct mid_q_entry *mid) 822cifs_echo_callback(struct mid_q_entry *mid)
823{ 823{
824 struct TCP_Server_Info *server = mid->callback_data; 824 struct TCP_Server_Info *server = mid->callback_data;
825 struct cifs_credits credits = { .value = 1, .instance = 0 };
825 826
826 DeleteMidQEntry(mid); 827 DeleteMidQEntry(mid);
827 add_credits(server, 1, CIFS_ECHO_OP); 828 add_credits(server, &credits, CIFS_ECHO_OP);
828} 829}
829 830
830int 831int
@@ -859,7 +860,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
859 iov[1].iov_base = (char *)smb + 4; 860 iov[1].iov_base = (char *)smb + 4;
860 861
861 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL, 862 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
862 server, CIFS_ASYNC_OP | CIFS_ECHO_OP); 863 server, CIFS_ASYNC_OP | CIFS_ECHO_OP, NULL);
863 if (rc) 864 if (rc)
864 cifs_dbg(FYI, "Echo request failed: %d\n", rc); 865 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
865 866
@@ -1605,16 +1606,17 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1605 } 1606 }
1606 1607
1607 if (server->ops->is_status_pending && 1608 if (server->ops->is_status_pending &&
1608 server->ops->is_status_pending(buf, server, 0)) { 1609 server->ops->is_status_pending(buf, server)) {
1609 cifs_discard_remaining_data(server); 1610 cifs_discard_remaining_data(server);
1610 return -1; 1611 return -1;
1611 } 1612 }
1612 1613
1613 /* set up first two iov for signature check and to get credits */ 1614 /* set up first two iov for signature check and to get credits */
1614 rdata->iov[0].iov_base = buf; 1615 rdata->iov[0].iov_base = buf;
1615 rdata->iov[0].iov_len = 4; 1616 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1616 rdata->iov[1].iov_base = buf + 4; 1617 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1617 rdata->iov[1].iov_len = server->total_read - 4; 1618 rdata->iov[1].iov_len =
1619 server->total_read - server->vals->header_preamble_size;
1618 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n", 1620 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1619 rdata->iov[0].iov_base, rdata->iov[0].iov_len); 1621 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1620 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n", 1622 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
@@ -1713,6 +1715,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
1713 .rq_npages = rdata->nr_pages, 1715 .rq_npages = rdata->nr_pages,
1714 .rq_pagesz = rdata->pagesz, 1716 .rq_pagesz = rdata->pagesz,
1715 .rq_tailsz = rdata->tailsz }; 1717 .rq_tailsz = rdata->tailsz };
1718 struct cifs_credits credits = { .value = 1, .instance = 0 };
1716 1719
1717 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n", 1720 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1718 __func__, mid->mid, mid->mid_state, rdata->result, 1721 __func__, mid->mid, mid->mid_state, rdata->result,
@@ -1750,7 +1753,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
1750 1753
1751 queue_work(cifsiod_wq, &rdata->work); 1754 queue_work(cifsiod_wq, &rdata->work);
1752 DeleteMidQEntry(mid); 1755 DeleteMidQEntry(mid);
1753 add_credits(server, 1, 0); 1756 add_credits(server, &credits, 0);
1754} 1757}
1755 1758
1756/* cifs_async_readv - send an async write, and set up mid to handle result */ 1759/* cifs_async_readv - send an async write, and set up mid to handle result */
@@ -1809,7 +1812,7 @@ cifs_async_readv(struct cifs_readdata *rdata)
1809 1812
1810 kref_get(&rdata->refcount); 1813 kref_get(&rdata->refcount);
1811 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, 1814 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1812 cifs_readv_callback, NULL, rdata, 0); 1815 cifs_readv_callback, NULL, rdata, 0, NULL);
1813 1816
1814 if (rc == 0) 1817 if (rc == 0)
1815 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1818 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
@@ -2123,14 +2126,18 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
2123 wdata2->tailsz = tailsz; 2126 wdata2->tailsz = tailsz;
2124 wdata2->bytes = cur_len; 2127 wdata2->bytes = cur_len;
2125 2128
2126 wdata2->cfile = find_writable_file(CIFS_I(inode), false); 2129 rc = cifs_get_writable_file(CIFS_I(inode), false,
2130 &wdata2->cfile);
2127 if (!wdata2->cfile) { 2131 if (!wdata2->cfile) {
2128 cifs_dbg(VFS, "No writable handles for inode\n"); 2132 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2129 rc = -EBADF; 2133 rc);
2130 break; 2134 if (!is_retryable_error(rc))
2135 rc = -EBADF;
2136 } else {
2137 wdata2->pid = wdata2->cfile->pid;
2138 rc = server->ops->async_writev(wdata2,
2139 cifs_writedata_release);
2131 } 2140 }
2132 wdata2->pid = wdata2->cfile->pid;
2133 rc = server->ops->async_writev(wdata2, cifs_writedata_release);
2134 2141
2135 for (j = 0; j < nr_pages; j++) { 2142 for (j = 0; j < nr_pages; j++) {
2136 unlock_page(wdata2->pages[j]); 2143 unlock_page(wdata2->pages[j]);
@@ -2145,6 +2152,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
2145 kref_put(&wdata2->refcount, cifs_writedata_release); 2152 kref_put(&wdata2->refcount, cifs_writedata_release);
2146 if (is_retryable_error(rc)) 2153 if (is_retryable_error(rc))
2147 continue; 2154 continue;
2155 i += nr_pages;
2148 break; 2156 break;
2149 } 2157 }
2150 2158
@@ -2152,6 +2160,13 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
2152 i += nr_pages; 2160 i += nr_pages;
2153 } while (i < wdata->nr_pages); 2161 } while (i < wdata->nr_pages);
2154 2162
2163 /* cleanup remaining pages from the original wdata */
2164 for (; i < wdata->nr_pages; i++) {
2165 SetPageError(wdata->pages[i]);
2166 end_page_writeback(wdata->pages[i]);
2167 put_page(wdata->pages[i]);
2168 }
2169
2155 if (rc != 0 && !is_retryable_error(rc)) 2170 if (rc != 0 && !is_retryable_error(rc))
2156 mapping_set_error(inode->i_mapping, rc); 2171 mapping_set_error(inode->i_mapping, rc);
2157 kref_put(&wdata->refcount, cifs_writedata_release); 2172 kref_put(&wdata->refcount, cifs_writedata_release);
@@ -2226,6 +2241,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
2226 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); 2241 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2227 unsigned int written; 2242 unsigned int written;
2228 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; 2243 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2244 struct cifs_credits credits = { .value = 1, .instance = 0 };
2229 2245
2230 switch (mid->mid_state) { 2246 switch (mid->mid_state) {
2231 case MID_RESPONSE_RECEIVED: 2247 case MID_RESPONSE_RECEIVED:
@@ -2261,7 +2277,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
2261 2277
2262 queue_work(cifsiod_wq, &wdata->work); 2278 queue_work(cifsiod_wq, &wdata->work);
2263 DeleteMidQEntry(mid); 2279 DeleteMidQEntry(mid);
2264 add_credits(tcon->ses->server, 1, 0); 2280 add_credits(tcon->ses->server, &credits, 0);
2265} 2281}
2266 2282
2267/* cifs_async_writev - send an async write, and set up mid to handle result */ 2283/* cifs_async_writev - send an async write, and set up mid to handle result */
@@ -2339,7 +2355,7 @@ cifs_async_writev(struct cifs_writedata *wdata,
2339 2355
2340 kref_get(&wdata->refcount); 2356 kref_get(&wdata->refcount);
2341 rc = cifs_call_async(tcon->ses->server, &rqst, NULL, 2357 rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2342 cifs_writev_callback, NULL, wdata, 0); 2358 cifs_writev_callback, NULL, wdata, 0, NULL);
2343 2359
2344 if (rc == 0) 2360 if (rc == 0)
2345 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 2361 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8463c940e0e5..b95db2b593cb 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -102,7 +102,7 @@ enum {
102 Opt_backupuid, Opt_backupgid, Opt_uid, 102 Opt_backupuid, Opt_backupgid, Opt_uid,
103 Opt_cruid, Opt_gid, Opt_file_mode, 103 Opt_cruid, Opt_gid, Opt_file_mode,
104 Opt_dirmode, Opt_port, 104 Opt_dirmode, Opt_port,
105 Opt_rsize, Opt_wsize, Opt_actimeo, 105 Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
106 Opt_echo_interval, Opt_max_credits, 106 Opt_echo_interval, Opt_max_credits,
107 Opt_snapshot, 107 Opt_snapshot,
108 108
@@ -204,6 +204,7 @@ static const match_table_t cifs_mount_option_tokens = {
204 { Opt_dirmode, "dirmode=%s" }, 204 { Opt_dirmode, "dirmode=%s" },
205 { Opt_dirmode, "dir_mode=%s" }, 205 { Opt_dirmode, "dir_mode=%s" },
206 { Opt_port, "port=%s" }, 206 { Opt_port, "port=%s" },
207 { Opt_blocksize, "bsize=%s" },
207 { Opt_rsize, "rsize=%s" }, 208 { Opt_rsize, "rsize=%s" },
208 { Opt_wsize, "wsize=%s" }, 209 { Opt_wsize, "wsize=%s" },
209 { Opt_actimeo, "actimeo=%s" }, 210 { Opt_actimeo, "actimeo=%s" },
@@ -348,7 +349,7 @@ static int reconn_set_ipaddr(struct TCP_Server_Info *server)
348 cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__); 349 cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__);
349 return -ENOMEM; 350 return -ENOMEM;
350 } 351 }
351 snprintf(unc, len, "\\\\%s", server->hostname); 352 scnprintf(unc, len, "\\\\%s", server->hostname);
352 353
353 rc = dns_resolve_server_name_to_ip(unc, &ipaddr); 354 rc = dns_resolve_server_name_to_ip(unc, &ipaddr);
354 kfree(unc); 355 kfree(unc);
@@ -592,6 +593,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
592 msleep(3000); 593 msleep(3000);
593 } else { 594 } else {
594 atomic_inc(&tcpSesReconnectCount); 595 atomic_inc(&tcpSesReconnectCount);
596 set_credits(server, 1);
595 spin_lock(&GlobalMid_Lock); 597 spin_lock(&GlobalMid_Lock);
596 if (server->tcpStatus != CifsExiting) 598 if (server->tcpStatus != CifsExiting)
597 server->tcpStatus = CifsNeedNegotiate; 599 server->tcpStatus = CifsNeedNegotiate;
@@ -1053,7 +1055,7 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1053 } 1055 }
1054 1056
1055 if (server->ops->is_status_pending && 1057 if (server->ops->is_status_pending &&
1056 server->ops->is_status_pending(buf, server, length)) 1058 server->ops->is_status_pending(buf, server))
1057 return -1; 1059 return -1;
1058 1060
1059 if (!mid) 1061 if (!mid)
@@ -1063,6 +1065,26 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1063 return 0; 1065 return 0;
1064} 1066}
1065 1067
1068static void
1069smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
1070{
1071 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
1072
1073 /*
1074 * SMB1 does not use credits.
1075 */
1076 if (server->vals->header_preamble_size)
1077 return;
1078
1079 if (shdr->CreditRequest) {
1080 spin_lock(&server->req_lock);
1081 server->credits += le16_to_cpu(shdr->CreditRequest);
1082 spin_unlock(&server->req_lock);
1083 wake_up(&server->request_q);
1084 }
1085}
1086
1087
1066static int 1088static int
1067cifs_demultiplex_thread(void *p) 1089cifs_demultiplex_thread(void *p)
1068{ 1090{
@@ -1192,6 +1214,7 @@ next_pdu:
1192 } else if (server->ops->is_oplock_break && 1214 } else if (server->ops->is_oplock_break &&
1193 server->ops->is_oplock_break(bufs[i], 1215 server->ops->is_oplock_break(bufs[i],
1194 server)) { 1216 server)) {
1217 smb2_add_credits_from_hdr(bufs[i], server);
1195 cifs_dbg(FYI, "Received oplock break\n"); 1218 cifs_dbg(FYI, "Received oplock break\n");
1196 } else { 1219 } else {
1197 cifs_dbg(VFS, "No task to wake, unknown frame " 1220 cifs_dbg(VFS, "No task to wake, unknown frame "
@@ -1203,6 +1226,7 @@ next_pdu:
1203 if (server->ops->dump_detail) 1226 if (server->ops->dump_detail)
1204 server->ops->dump_detail(bufs[i], 1227 server->ops->dump_detail(bufs[i],
1205 server); 1228 server);
1229 smb2_add_credits_from_hdr(bufs[i], server);
1206 cifs_dump_mids(server); 1230 cifs_dump_mids(server);
1207#endif /* CIFS_DEBUG2 */ 1231#endif /* CIFS_DEBUG2 */
1208 } 1232 }
@@ -1486,6 +1510,11 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
1486 const char *delims = "/\\"; 1510 const char *delims = "/\\";
1487 size_t len; 1511 size_t len;
1488 1512
1513 if (unlikely(!devname || !*devname)) {
1514 cifs_dbg(VFS, "Device name not specified.\n");
1515 return -EINVAL;
1516 }
1517
1489 /* make sure we have a valid UNC double delimiter prefix */ 1518 /* make sure we have a valid UNC double delimiter prefix */
1490 len = strspn(devname, delims); 1519 len = strspn(devname, delims);
1491 if (len != 2) 1520 if (len != 2)
@@ -1571,7 +1600,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1571 vol->cred_uid = current_uid(); 1600 vol->cred_uid = current_uid();
1572 vol->linux_uid = current_uid(); 1601 vol->linux_uid = current_uid();
1573 vol->linux_gid = current_gid(); 1602 vol->linux_gid = current_gid();
1574 1603 vol->bsize = 1024 * 1024; /* can improve cp performance significantly */
1575 /* 1604 /*
1576 * default to SFM style remapping of seven reserved characters 1605 * default to SFM style remapping of seven reserved characters
1577 * unless user overrides it or we negotiate CIFS POSIX where 1606 * unless user overrides it or we negotiate CIFS POSIX where
@@ -1944,6 +1973,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1944 } 1973 }
1945 port = (unsigned short)option; 1974 port = (unsigned short)option;
1946 break; 1975 break;
1976 case Opt_blocksize:
1977 if (get_option_ul(args, &option)) {
1978 cifs_dbg(VFS, "%s: Invalid blocksize value\n",
1979 __func__);
1980 goto cifs_parse_mount_err;
1981 }
1982 /*
1983 * inode blocksize realistically should never need to be
1984 * less than 16K or greater than 16M and default is 1MB.
1985 * Note that small inode block sizes (e.g. 64K) can lead
1986 * to very poor performance of common tools like cp and scp
1987 */
1988 if ((option < CIFS_MAX_MSGSIZE) ||
1989 (option > (4 * SMB3_DEFAULT_IOSIZE))) {
1990 cifs_dbg(VFS, "%s: Invalid blocksize\n",
1991 __func__);
1992 goto cifs_parse_mount_err;
1993 }
1994 vol->bsize = option;
1995 break;
1947 case Opt_rsize: 1996 case Opt_rsize:
1948 if (get_option_ul(args, &option)) { 1997 if (get_option_ul(args, &option)) {
1949 cifs_dbg(VFS, "%s: Invalid rsize value\n", 1998 cifs_dbg(VFS, "%s: Invalid rsize value\n",
@@ -2609,7 +2658,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2609 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 2658 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
2610 tcp_ses->session_estab = false; 2659 tcp_ses->session_estab = false;
2611 tcp_ses->sequence_number = 0; 2660 tcp_ses->sequence_number = 0;
2612 tcp_ses->reconnect_instance = 0; 2661 tcp_ses->reconnect_instance = 1;
2613 tcp_ses->lstrp = jiffies; 2662 tcp_ses->lstrp = jiffies;
2614 spin_lock_init(&tcp_ses->req_lock); 2663 spin_lock_init(&tcp_ses->req_lock);
2615 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 2664 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
@@ -2770,7 +2819,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info)
2770 if (tcon == NULL) 2819 if (tcon == NULL)
2771 return -ENOMEM; 2820 return -ENOMEM;
2772 2821
2773 snprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname); 2822 scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname);
2774 2823
2775 /* cannot fail */ 2824 /* cannot fail */
2776 nls_codepage = load_nls_default(); 2825 nls_codepage = load_nls_default();
@@ -3839,6 +3888,7 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
3839 spin_lock_init(&cifs_sb->tlink_tree_lock); 3888 spin_lock_init(&cifs_sb->tlink_tree_lock);
3840 cifs_sb->tlink_tree = RB_ROOT; 3889 cifs_sb->tlink_tree = RB_ROOT;
3841 3890
3891 cifs_sb->bsize = pvolume_info->bsize;
3842 /* 3892 /*
3843 * Temporarily set r/wsize for matching superblock. If we end up using 3893 * Temporarily set r/wsize for matching superblock. If we end up using
3844 * new sb then client will later negotiate it downward if needed. 3894 * new sb then client will later negotiate it downward if needed.
@@ -4198,7 +4248,7 @@ static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it,
4198 new_unc = kmalloc(len, GFP_KERNEL); 4248 new_unc = kmalloc(len, GFP_KERNEL);
4199 if (!new_unc) 4249 if (!new_unc)
4200 return -ENOMEM; 4250 return -ENOMEM;
4201 snprintf(new_unc, len, "\\%s", tgt); 4251 scnprintf(new_unc, len, "\\%s", tgt);
4202 4252
4203 kfree(vol->UNC); 4253 kfree(vol->UNC);
4204 vol->UNC = new_unc; 4254 vol->UNC = new_unc;
@@ -4902,8 +4952,6 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
4902 if (!server->ops->need_neg(server)) 4952 if (!server->ops->need_neg(server))
4903 return 0; 4953 return 0;
4904 4954
4905 set_credits(server, 1);
4906
4907 rc = server->ops->negotiate(xid, ses); 4955 rc = server->ops->negotiate(xid, ses);
4908 if (rc == 0) { 4956 if (rc == 0) {
4909 spin_lock(&GlobalMid_Lock); 4957 spin_lock(&GlobalMid_Lock);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 659ce1b92c44..4c144c1f50eb 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1842,24 +1842,30 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1842 return NULL; 1842 return NULL;
1843} 1843}
1844 1844
1845struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, 1845/* Return -EBADF if no handle is found and general rc otherwise */
1846 bool fsuid_only) 1846int
1847cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
1848 struct cifsFileInfo **ret_file)
1847{ 1849{
1848 struct cifsFileInfo *open_file, *inv_file = NULL; 1850 struct cifsFileInfo *open_file, *inv_file = NULL;
1849 struct cifs_sb_info *cifs_sb; 1851 struct cifs_sb_info *cifs_sb;
1850 struct cifs_tcon *tcon; 1852 struct cifs_tcon *tcon;
1851 bool any_available = false; 1853 bool any_available = false;
1852 int rc; 1854 int rc = -EBADF;
1853 unsigned int refind = 0; 1855 unsigned int refind = 0;
1854 1856
1855 /* Having a null inode here (because mapping->host was set to zero by 1857 *ret_file = NULL;
1856 the VFS or MM) should not happen but we had reports of on oops (due to 1858
1857 it being zero) during stress testcases so we need to check for it */ 1859 /*
1860 * Having a null inode here (because mapping->host was set to zero by
1861 * the VFS or MM) should not happen but we had reports of on oops (due
1862 * to it being zero) during stress testcases so we need to check for it
1863 */
1858 1864
1859 if (cifs_inode == NULL) { 1865 if (cifs_inode == NULL) {
1860 cifs_dbg(VFS, "Null inode passed to cifs_writeable_file\n"); 1866 cifs_dbg(VFS, "Null inode passed to cifs_writeable_file\n");
1861 dump_stack(); 1867 dump_stack();
1862 return NULL; 1868 return rc;
1863 } 1869 }
1864 1870
1865 cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); 1871 cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
@@ -1873,7 +1879,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1873refind_writable: 1879refind_writable:
1874 if (refind > MAX_REOPEN_ATT) { 1880 if (refind > MAX_REOPEN_ATT) {
1875 spin_unlock(&tcon->open_file_lock); 1881 spin_unlock(&tcon->open_file_lock);
1876 return NULL; 1882 return rc;
1877 } 1883 }
1878 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1884 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1879 if (!any_available && open_file->pid != current->tgid) 1885 if (!any_available && open_file->pid != current->tgid)
@@ -1885,7 +1891,8 @@ refind_writable:
1885 /* found a good writable file */ 1891 /* found a good writable file */
1886 cifsFileInfo_get(open_file); 1892 cifsFileInfo_get(open_file);
1887 spin_unlock(&tcon->open_file_lock); 1893 spin_unlock(&tcon->open_file_lock);
1888 return open_file; 1894 *ret_file = open_file;
1895 return 0;
1889 } else { 1896 } else {
1890 if (!inv_file) 1897 if (!inv_file)
1891 inv_file = open_file; 1898 inv_file = open_file;
@@ -1907,22 +1914,35 @@ refind_writable:
1907 1914
1908 if (inv_file) { 1915 if (inv_file) {
1909 rc = cifs_reopen_file(inv_file, false); 1916 rc = cifs_reopen_file(inv_file, false);
1910 if (!rc) 1917 if (!rc) {
1911 return inv_file; 1918 *ret_file = inv_file;
1912 else { 1919 return 0;
1913 spin_lock(&tcon->open_file_lock);
1914 list_move_tail(&inv_file->flist,
1915 &cifs_inode->openFileList);
1916 spin_unlock(&tcon->open_file_lock);
1917 cifsFileInfo_put(inv_file);
1918 ++refind;
1919 inv_file = NULL;
1920 spin_lock(&tcon->open_file_lock);
1921 goto refind_writable;
1922 } 1920 }
1921
1922 spin_lock(&tcon->open_file_lock);
1923 list_move_tail(&inv_file->flist, &cifs_inode->openFileList);
1924 spin_unlock(&tcon->open_file_lock);
1925 cifsFileInfo_put(inv_file);
1926 ++refind;
1927 inv_file = NULL;
1928 spin_lock(&tcon->open_file_lock);
1929 goto refind_writable;
1923 } 1930 }
1924 1931
1925 return NULL; 1932 return rc;
1933}
1934
1935struct cifsFileInfo *
1936find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
1937{
1938 struct cifsFileInfo *cfile;
1939 int rc;
1940
1941 rc = cifs_get_writable_file(cifs_inode, fsuid_only, &cfile);
1942 if (rc)
1943 cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
1944
1945 return cfile;
1926} 1946}
1927 1947
1928static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) 1948static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
@@ -1959,8 +1979,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1959 if (mapping->host->i_size - offset < (loff_t)to) 1979 if (mapping->host->i_size - offset < (loff_t)to)
1960 to = (unsigned)(mapping->host->i_size - offset); 1980 to = (unsigned)(mapping->host->i_size - offset);
1961 1981
1962 open_file = find_writable_file(CIFS_I(mapping->host), false); 1982 rc = cifs_get_writable_file(CIFS_I(mapping->host), false, &open_file);
1963 if (open_file) { 1983 if (!rc) {
1964 bytes_written = cifs_write(open_file, open_file->pid, 1984 bytes_written = cifs_write(open_file, open_file->pid,
1965 write_data, to - from, &offset); 1985 write_data, to - from, &offset);
1966 cifsFileInfo_put(open_file); 1986 cifsFileInfo_put(open_file);
@@ -1970,9 +1990,12 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1970 rc = 0; 1990 rc = 0;
1971 else if (bytes_written < 0) 1991 else if (bytes_written < 0)
1972 rc = bytes_written; 1992 rc = bytes_written;
1993 else
1994 rc = -EFAULT;
1973 } else { 1995 } else {
1974 cifs_dbg(FYI, "No writeable filehandles for inode\n"); 1996 cifs_dbg(FYI, "No writable handle for write page rc=%d\n", rc);
1975 rc = -EIO; 1997 if (!is_retryable_error(rc))
1998 rc = -EIO;
1976 } 1999 }
1977 2000
1978 kunmap(page); 2001 kunmap(page);
@@ -2079,9 +2102,9 @@ static int
2079wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages, 2102wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2080 struct address_space *mapping, struct writeback_control *wbc) 2103 struct address_space *mapping, struct writeback_control *wbc)
2081{ 2104{
2082 int rc = 0; 2105 int rc;
2083 struct TCP_Server_Info *server; 2106 struct TCP_Server_Info *server =
2084 unsigned int i; 2107 tlink_tcon(wdata->cfile->tlink)->ses->server;
2085 2108
2086 wdata->sync_mode = wbc->sync_mode; 2109 wdata->sync_mode = wbc->sync_mode;
2087 wdata->nr_pages = nr_pages; 2110 wdata->nr_pages = nr_pages;
@@ -2091,21 +2114,16 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2091 page_offset(wdata->pages[nr_pages - 1]), 2114 page_offset(wdata->pages[nr_pages - 1]),
2092 (loff_t)PAGE_SIZE); 2115 (loff_t)PAGE_SIZE);
2093 wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz; 2116 wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz;
2117 wdata->pid = wdata->cfile->pid;
2094 2118
2095 if (wdata->cfile != NULL) 2119 rc = adjust_credits(server, &wdata->credits, wdata->bytes);
2096 cifsFileInfo_put(wdata->cfile); 2120 if (rc)
2097 wdata->cfile = find_writable_file(CIFS_I(mapping->host), false); 2121 return rc;
2098 if (!wdata->cfile) {
2099 cifs_dbg(VFS, "No writable handles for inode\n");
2100 rc = -EBADF;
2101 } else {
2102 wdata->pid = wdata->cfile->pid;
2103 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2104 rc = server->ops->async_writev(wdata, cifs_writedata_release);
2105 }
2106 2122
2107 for (i = 0; i < nr_pages; ++i) 2123 if (wdata->cfile->invalidHandle)
2108 unlock_page(wdata->pages[i]); 2124 rc = -EAGAIN;
2125 else
2126 rc = server->ops->async_writev(wdata, cifs_writedata_release);
2109 2127
2110 return rc; 2128 return rc;
2111} 2129}
@@ -2113,11 +2131,13 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2113static int cifs_writepages(struct address_space *mapping, 2131static int cifs_writepages(struct address_space *mapping,
2114 struct writeback_control *wbc) 2132 struct writeback_control *wbc)
2115{ 2133{
2116 struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb); 2134 struct inode *inode = mapping->host;
2135 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2117 struct TCP_Server_Info *server; 2136 struct TCP_Server_Info *server;
2118 bool done = false, scanned = false, range_whole = false; 2137 bool done = false, scanned = false, range_whole = false;
2119 pgoff_t end, index; 2138 pgoff_t end, index;
2120 struct cifs_writedata *wdata; 2139 struct cifs_writedata *wdata;
2140 struct cifsFileInfo *cfile = NULL;
2121 int rc = 0; 2141 int rc = 0;
2122 int saved_rc = 0; 2142 int saved_rc = 0;
2123 unsigned int xid; 2143 unsigned int xid;
@@ -2143,11 +2163,23 @@ static int cifs_writepages(struct address_space *mapping,
2143 server = cifs_sb_master_tcon(cifs_sb)->ses->server; 2163 server = cifs_sb_master_tcon(cifs_sb)->ses->server;
2144retry: 2164retry:
2145 while (!done && index <= end) { 2165 while (!done && index <= end) {
2146 unsigned int i, nr_pages, found_pages, wsize, credits; 2166 unsigned int i, nr_pages, found_pages, wsize;
2147 pgoff_t next = 0, tofind, saved_index = index; 2167 pgoff_t next = 0, tofind, saved_index = index;
2168 struct cifs_credits credits_on_stack;
2169 struct cifs_credits *credits = &credits_on_stack;
2170 int get_file_rc = 0;
2171
2172 if (cfile)
2173 cifsFileInfo_put(cfile);
2174
2175 rc = cifs_get_writable_file(CIFS_I(inode), false, &cfile);
2176
2177 /* in case of an error store it to return later */
2178 if (rc)
2179 get_file_rc = rc;
2148 2180
2149 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2181 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2150 &wsize, &credits); 2182 &wsize, credits);
2151 if (rc != 0) { 2183 if (rc != 0) {
2152 done = true; 2184 done = true;
2153 break; 2185 break;
@@ -2180,13 +2212,26 @@ retry:
2180 continue; 2212 continue;
2181 } 2213 }
2182 2214
2183 wdata->credits = credits; 2215 wdata->credits = credits_on_stack;
2216 wdata->cfile = cfile;
2217 cfile = NULL;
2184 2218
2185 rc = wdata_send_pages(wdata, nr_pages, mapping, wbc); 2219 if (!wdata->cfile) {
2220 cifs_dbg(VFS, "No writable handle in writepages rc=%d\n",
2221 get_file_rc);
2222 if (is_retryable_error(get_file_rc))
2223 rc = get_file_rc;
2224 else
2225 rc = -EBADF;
2226 } else
2227 rc = wdata_send_pages(wdata, nr_pages, mapping, wbc);
2228
2229 for (i = 0; i < nr_pages; ++i)
2230 unlock_page(wdata->pages[i]);
2186 2231
2187 /* send failure -- clean up the mess */ 2232 /* send failure -- clean up the mess */
2188 if (rc != 0) { 2233 if (rc != 0) {
2189 add_credits_and_wake_if(server, wdata->credits, 0); 2234 add_credits_and_wake_if(server, &wdata->credits, 0);
2190 for (i = 0; i < nr_pages; ++i) { 2235 for (i = 0; i < nr_pages; ++i) {
2191 if (is_retryable_error(rc)) 2236 if (is_retryable_error(rc))
2192 redirty_page_for_writepage(wbc, 2237 redirty_page_for_writepage(wbc,
@@ -2238,6 +2283,8 @@ retry:
2238 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) 2283 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
2239 mapping->writeback_index = index; 2284 mapping->writeback_index = index;
2240 2285
2286 if (cfile)
2287 cifsFileInfo_put(cfile);
2241 free_xid(xid); 2288 free_xid(xid);
2242 return rc; 2289 return rc;
2243} 2290}
@@ -2567,7 +2614,8 @@ static int
2567cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list, 2614cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2568 struct cifs_aio_ctx *ctx) 2615 struct cifs_aio_ctx *ctx)
2569{ 2616{
2570 unsigned int wsize, credits; 2617 unsigned int wsize;
2618 struct cifs_credits credits;
2571 int rc; 2619 int rc;
2572 struct TCP_Server_Info *server = 2620 struct TCP_Server_Info *server =
2573 tlink_tcon(wdata->cfile->tlink)->ses->server; 2621 tlink_tcon(wdata->cfile->tlink)->ses->server;
@@ -2577,18 +2625,19 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2577 * Note: we are attempting to resend the whole wdata not in segments 2625 * Note: we are attempting to resend the whole wdata not in segments
2578 */ 2626 */
2579 do { 2627 do {
2580 rc = server->ops->wait_mtu_credits( 2628 rc = server->ops->wait_mtu_credits(server, wdata->bytes, &wsize,
2581 server, wdata->bytes, &wsize, &credits); 2629 &credits);
2582 2630
2583 if (rc) 2631 if (rc)
2584 goto out; 2632 goto out;
2585 2633
2586 if (wsize < wdata->bytes) { 2634 if (wsize < wdata->bytes) {
2587 add_credits_and_wake_if(server, credits, 0); 2635 add_credits_and_wake_if(server, &credits, 0);
2588 msleep(1000); 2636 msleep(1000);
2589 } 2637 }
2590 } while (wsize < wdata->bytes); 2638 } while (wsize < wdata->bytes);
2591 2639
2640 wdata->credits = credits;
2592 rc = -EAGAIN; 2641 rc = -EAGAIN;
2593 while (rc == -EAGAIN) { 2642 while (rc == -EAGAIN) {
2594 rc = 0; 2643 rc = 0;
@@ -2604,7 +2653,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2604 return 0; 2653 return 0;
2605 } 2654 }
2606 2655
2607 add_credits_and_wake_if(server, wdata->credits, 0); 2656 add_credits_and_wake_if(server, &wdata->credits, 0);
2608out: 2657out:
2609 kref_put(&wdata->refcount, cifs_uncached_writedata_release); 2658 kref_put(&wdata->refcount, cifs_uncached_writedata_release);
2610 2659
@@ -2627,6 +2676,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2627 struct TCP_Server_Info *server; 2676 struct TCP_Server_Info *server;
2628 struct page **pagevec; 2677 struct page **pagevec;
2629 size_t start; 2678 size_t start;
2679 unsigned int xid;
2630 2680
2631 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) 2681 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2632 pid = open_file->pid; 2682 pid = open_file->pid;
@@ -2634,12 +2684,23 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2634 pid = current->tgid; 2684 pid = current->tgid;
2635 2685
2636 server = tlink_tcon(open_file->tlink)->ses->server; 2686 server = tlink_tcon(open_file->tlink)->ses->server;
2687 xid = get_xid();
2637 2688
2638 do { 2689 do {
2639 unsigned int wsize, credits; 2690 unsigned int wsize;
2691 struct cifs_credits credits_on_stack;
2692 struct cifs_credits *credits = &credits_on_stack;
2693
2694 if (open_file->invalidHandle) {
2695 rc = cifs_reopen_file(open_file, false);
2696 if (rc == -EAGAIN)
2697 continue;
2698 else if (rc)
2699 break;
2700 }
2640 2701
2641 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2702 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2642 &wsize, &credits); 2703 &wsize, credits);
2643 if (rc) 2704 if (rc)
2644 break; 2705 break;
2645 2706
@@ -2731,16 +2792,22 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2731 wdata->pid = pid; 2792 wdata->pid = pid;
2732 wdata->bytes = cur_len; 2793 wdata->bytes = cur_len;
2733 wdata->pagesz = PAGE_SIZE; 2794 wdata->pagesz = PAGE_SIZE;
2734 wdata->credits = credits; 2795 wdata->credits = credits_on_stack;
2735 wdata->ctx = ctx; 2796 wdata->ctx = ctx;
2736 kref_get(&ctx->refcount); 2797 kref_get(&ctx->refcount);
2737 2798
2738 if (!wdata->cfile->invalidHandle || 2799 rc = adjust_credits(server, &wdata->credits, wdata->bytes);
2739 !(rc = cifs_reopen_file(wdata->cfile, false))) 2800
2740 rc = server->ops->async_writev(wdata, 2801 if (!rc) {
2802 if (wdata->cfile->invalidHandle)
2803 rc = -EAGAIN;
2804 else
2805 rc = server->ops->async_writev(wdata,
2741 cifs_uncached_writedata_release); 2806 cifs_uncached_writedata_release);
2807 }
2808
2742 if (rc) { 2809 if (rc) {
2743 add_credits_and_wake_if(server, wdata->credits, 0); 2810 add_credits_and_wake_if(server, &wdata->credits, 0);
2744 kref_put(&wdata->refcount, 2811 kref_put(&wdata->refcount,
2745 cifs_uncached_writedata_release); 2812 cifs_uncached_writedata_release);
2746 if (rc == -EAGAIN) { 2813 if (rc == -EAGAIN) {
@@ -2756,6 +2823,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2756 len -= cur_len; 2823 len -= cur_len;
2757 } while (len > 0); 2824 } while (len > 0);
2758 2825
2826 free_xid(xid);
2759 return rc; 2827 return rc;
2760} 2828}
2761 2829
@@ -3028,14 +3096,16 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
3028 * these pages but not on the region from pos to ppos+len-1. 3096 * these pages but not on the region from pos to ppos+len-1.
3029 */ 3097 */
3030 written = cifs_user_writev(iocb, from); 3098 written = cifs_user_writev(iocb, from);
3031 if (written > 0 && CIFS_CACHE_READ(cinode)) { 3099 if (CIFS_CACHE_READ(cinode)) {
3032 /* 3100 /*
3033 * Windows 7 server can delay breaking level2 oplock if a write 3101 * We have read level caching and we have just sent a write
3034 * request comes - break it on the client to prevent reading 3102 * request to the server thus making data in the cache stale.
3035 * an old data. 3103 * Zap the cache and set oplock/lease level to NONE to avoid
3104 * reading stale data from the cache. All subsequent read
3105 * operations will read new data from the server.
3036 */ 3106 */
3037 cifs_zap_mapping(inode); 3107 cifs_zap_mapping(inode);
3038 cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n", 3108 cifs_dbg(FYI, "Set Oplock/Lease to NONE for inode=%p after write\n",
3039 inode); 3109 inode);
3040 cinode->oplock = 0; 3110 cinode->oplock = 0;
3041 } 3111 }
@@ -3260,7 +3330,8 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3260 struct list_head *rdata_list, 3330 struct list_head *rdata_list,
3261 struct cifs_aio_ctx *ctx) 3331 struct cifs_aio_ctx *ctx)
3262{ 3332{
3263 unsigned int rsize, credits; 3333 unsigned int rsize;
3334 struct cifs_credits credits;
3264 int rc; 3335 int rc;
3265 struct TCP_Server_Info *server = 3336 struct TCP_Server_Info *server =
3266 tlink_tcon(rdata->cfile->tlink)->ses->server; 3337 tlink_tcon(rdata->cfile->tlink)->ses->server;
@@ -3277,11 +3348,12 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3277 goto out; 3348 goto out;
3278 3349
3279 if (rsize < rdata->bytes) { 3350 if (rsize < rdata->bytes) {
3280 add_credits_and_wake_if(server, credits, 0); 3351 add_credits_and_wake_if(server, &credits, 0);
3281 msleep(1000); 3352 msleep(1000);
3282 } 3353 }
3283 } while (rsize < rdata->bytes); 3354 } while (rsize < rdata->bytes);
3284 3355
3356 rdata->credits = credits;
3285 rc = -EAGAIN; 3357 rc = -EAGAIN;
3286 while (rc == -EAGAIN) { 3358 while (rc == -EAGAIN) {
3287 rc = 0; 3359 rc = 0;
@@ -3297,7 +3369,7 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3297 return 0; 3369 return 0;
3298 } 3370 }
3299 3371
3300 add_credits_and_wake_if(server, rdata->credits, 0); 3372 add_credits_and_wake_if(server, &rdata->credits, 0);
3301out: 3373out:
3302 kref_put(&rdata->refcount, 3374 kref_put(&rdata->refcount,
3303 cifs_uncached_readdata_release); 3375 cifs_uncached_readdata_release);
@@ -3311,7 +3383,9 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
3311 struct cifs_aio_ctx *ctx) 3383 struct cifs_aio_ctx *ctx)
3312{ 3384{
3313 struct cifs_readdata *rdata; 3385 struct cifs_readdata *rdata;
3314 unsigned int npages, rsize, credits; 3386 unsigned int npages, rsize;
3387 struct cifs_credits credits_on_stack;
3388 struct cifs_credits *credits = &credits_on_stack;
3315 size_t cur_len; 3389 size_t cur_len;
3316 int rc; 3390 int rc;
3317 pid_t pid; 3391 pid_t pid;
@@ -3331,8 +3405,16 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
3331 iov_iter_advance(&direct_iov, offset - ctx->pos); 3405 iov_iter_advance(&direct_iov, offset - ctx->pos);
3332 3406
3333 do { 3407 do {
3408 if (open_file->invalidHandle) {
3409 rc = cifs_reopen_file(open_file, true);
3410 if (rc == -EAGAIN)
3411 continue;
3412 else if (rc)
3413 break;
3414 }
3415
3334 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, 3416 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
3335 &rsize, &credits); 3417 &rsize, credits);
3336 if (rc) 3418 if (rc)
3337 break; 3419 break;
3338 3420
@@ -3406,15 +3488,21 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
3406 rdata->pagesz = PAGE_SIZE; 3488 rdata->pagesz = PAGE_SIZE;
3407 rdata->read_into_pages = cifs_uncached_read_into_pages; 3489 rdata->read_into_pages = cifs_uncached_read_into_pages;
3408 rdata->copy_into_pages = cifs_uncached_copy_into_pages; 3490 rdata->copy_into_pages = cifs_uncached_copy_into_pages;
3409 rdata->credits = credits; 3491 rdata->credits = credits_on_stack;
3410 rdata->ctx = ctx; 3492 rdata->ctx = ctx;
3411 kref_get(&ctx->refcount); 3493 kref_get(&ctx->refcount);
3412 3494
3413 if (!rdata->cfile->invalidHandle || 3495 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
3414 !(rc = cifs_reopen_file(rdata->cfile, true))) 3496
3415 rc = server->ops->async_readv(rdata); 3497 if (!rc) {
3498 if (rdata->cfile->invalidHandle)
3499 rc = -EAGAIN;
3500 else
3501 rc = server->ops->async_readv(rdata);
3502 }
3503
3416 if (rc) { 3504 if (rc) {
3417 add_credits_and_wake_if(server, rdata->credits, 0); 3505 add_credits_and_wake_if(server, &rdata->credits, 0);
3418 kref_put(&rdata->refcount, 3506 kref_put(&rdata->refcount,
3419 cifs_uncached_readdata_release); 3507 cifs_uncached_readdata_release);
3420 if (rc == -EAGAIN) { 3508 if (rc == -EAGAIN) {
@@ -3533,8 +3621,6 @@ again:
3533 ctx->total_len = ctx->len - iov_iter_count(to); 3621 ctx->total_len = ctx->len - iov_iter_count(to);
3534 } 3622 }
3535 3623
3536 cifs_stats_bytes_read(tcon, ctx->total_len);
3537
3538 /* mask nodata case */ 3624 /* mask nodata case */
3539 if (rc == -ENODATA) 3625 if (rc == -ENODATA)
3540 rc = 0; 3626 rc = 0;
@@ -4095,10 +4181,19 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
4095 loff_t offset; 4181 loff_t offset;
4096 struct page *page, *tpage; 4182 struct page *page, *tpage;
4097 struct cifs_readdata *rdata; 4183 struct cifs_readdata *rdata;
4098 unsigned credits; 4184 struct cifs_credits credits_on_stack;
4185 struct cifs_credits *credits = &credits_on_stack;
4186
4187 if (open_file->invalidHandle) {
4188 rc = cifs_reopen_file(open_file, true);
4189 if (rc == -EAGAIN)
4190 continue;
4191 else if (rc)
4192 break;
4193 }
4099 4194
4100 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, 4195 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
4101 &rsize, &credits); 4196 &rsize, credits);
4102 if (rc) 4197 if (rc)
4103 break; 4198 break;
4104 4199
@@ -4144,18 +4239,24 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
4144 rdata->tailsz = PAGE_SIZE; 4239 rdata->tailsz = PAGE_SIZE;
4145 rdata->read_into_pages = cifs_readpages_read_into_pages; 4240 rdata->read_into_pages = cifs_readpages_read_into_pages;
4146 rdata->copy_into_pages = cifs_readpages_copy_into_pages; 4241 rdata->copy_into_pages = cifs_readpages_copy_into_pages;
4147 rdata->credits = credits; 4242 rdata->credits = credits_on_stack;
4148 4243
4149 list_for_each_entry_safe(page, tpage, &tmplist, lru) { 4244 list_for_each_entry_safe(page, tpage, &tmplist, lru) {
4150 list_del(&page->lru); 4245 list_del(&page->lru);
4151 rdata->pages[rdata->nr_pages++] = page; 4246 rdata->pages[rdata->nr_pages++] = page;
4152 } 4247 }
4153 4248
4154 if (!rdata->cfile->invalidHandle || 4249 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
4155 !(rc = cifs_reopen_file(rdata->cfile, true))) 4250
4156 rc = server->ops->async_readv(rdata); 4251 if (!rc) {
4252 if (rdata->cfile->invalidHandle)
4253 rc = -EAGAIN;
4254 else
4255 rc = server->ops->async_readv(rdata);
4256 }
4257
4157 if (rc) { 4258 if (rc) {
4158 add_credits_and_wake_if(server, rdata->credits, 0); 4259 add_credits_and_wake_if(server, &rdata->credits, 0);
4159 for (i = 0; i < rdata->nr_pages; i++) { 4260 for (i = 0; i < rdata->nr_pages; i++) {
4160 page = rdata->pages[i]; 4261 page = rdata->pages[i];
4161 lru_cache_add_file(page); 4262 lru_cache_add_file(page);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 478003644916..53fdb5df0d2e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2080,7 +2080,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat,
2080 return rc; 2080 return rc;
2081 2081
2082 generic_fillattr(inode, stat); 2082 generic_fillattr(inode, stat);
2083 stat->blksize = CIFS_MAX_MSGSIZE; 2083 stat->blksize = cifs_sb->bsize;
2084 stat->ino = CIFS_I(inode)->uniqueid; 2084 stat->ino = CIFS_I(inode)->uniqueid;
2085 2085
2086 /* old CIFS Unix Extensions doesn't return create time */ 2086 /* old CIFS Unix Extensions doesn't return create time */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 2148b0f60e5e..62216dc8f9f5 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -103,9 +103,9 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
103 return rc; 103 return rc;
104 } 104 }
105 105
106 snprintf(md5_str2, sizeof(md5_str2), 106 scnprintf(md5_str2, sizeof(md5_str2),
107 CIFS_MF_SYMLINK_MD5_FORMAT, 107 CIFS_MF_SYMLINK_MD5_FORMAT,
108 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 108 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
109 109
110 if (strncmp(md5_str1, md5_str2, 17) != 0) 110 if (strncmp(md5_str1, md5_str2, 17) != 0)
111 return -EINVAL; 111 return -EINVAL;
@@ -142,10 +142,10 @@ format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str)
142 return rc; 142 return rc;
143 } 143 }
144 144
145 snprintf(buf, buf_len, 145 scnprintf(buf, buf_len,
146 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, 146 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
147 link_len, 147 link_len,
148 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 148 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
149 149
150 ofs = CIFS_MF_SYMLINK_LINK_OFFSET; 150 ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
151 memcpy(buf + ofs, link_str, link_len); 151 memcpy(buf + ofs, link_str, link_len);
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 32a6c020478f..f0ce27c3c6e4 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -117,11 +117,11 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
117} 117}
118 118
119static void 119static void
120cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add, 120cifs_add_credits(struct TCP_Server_Info *server,
121 const int optype) 121 const struct cifs_credits *credits, const int optype)
122{ 122{
123 spin_lock(&server->req_lock); 123 spin_lock(&server->req_lock);
124 server->credits += add; 124 server->credits += credits->value;
125 server->in_flight--; 125 server->in_flight--;
126 spin_unlock(&server->req_lock); 126 spin_unlock(&server->req_lock);
127 wake_up(&server->request_q); 127 wake_up(&server->request_q);
@@ -308,7 +308,7 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
308 remaining = tgt_total_cnt - total_in_tgt; 308 remaining = tgt_total_cnt - total_in_tgt;
309 309
310 if (remaining < 0) { 310 if (remaining < 0) {
311 cifs_dbg(FYI, "Server sent too much data. tgt_total_cnt=%hu total_in_tgt=%hu\n", 311 cifs_dbg(FYI, "Server sent too much data. tgt_total_cnt=%hu total_in_tgt=%u\n",
312 tgt_total_cnt, total_in_tgt); 312 tgt_total_cnt, total_in_tgt);
313 return -EPROTO; 313 return -EPROTO;
314 } 314 }
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index 7b8b58fb4d3f..0e3570e40ff8 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -517,7 +517,6 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
517 __u8 lease_state; 517 __u8 lease_state;
518 struct list_head *tmp; 518 struct list_head *tmp;
519 struct cifsFileInfo *cfile; 519 struct cifsFileInfo *cfile;
520 struct TCP_Server_Info *server = tcon->ses->server;
521 struct cifs_pending_open *open; 520 struct cifs_pending_open *open;
522 struct cifsInodeInfo *cinode; 521 struct cifsInodeInfo *cinode;
523 int ack_req = le32_to_cpu(rsp->Flags & 522 int ack_req = le32_to_cpu(rsp->Flags &
@@ -537,13 +536,25 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
537 cifs_dbg(FYI, "lease key match, lease break 0x%x\n", 536 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
538 le32_to_cpu(rsp->NewLeaseState)); 537 le32_to_cpu(rsp->NewLeaseState));
539 538
540 server->ops->set_oplock_level(cinode, lease_state, 0, NULL);
541
542 if (ack_req) 539 if (ack_req)
543 cfile->oplock_break_cancelled = false; 540 cfile->oplock_break_cancelled = false;
544 else 541 else
545 cfile->oplock_break_cancelled = true; 542 cfile->oplock_break_cancelled = true;
546 543
544 set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);
545
546 /*
547 * Set or clear flags depending on the lease state being READ.
548 * HANDLE caching flag should be added when the client starts
549 * to defer closing remote file handles with HANDLE leases.
550 */
551 if (lease_state & SMB2_LEASE_READ_CACHING_HE)
552 set_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
553 &cinode->flags);
554 else
555 clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
556 &cinode->flags);
557
547 queue_work(cifsoplockd_wq, &cfile->oplock_break); 558 queue_work(cifsoplockd_wq, &cfile->oplock_break);
548 kfree(lw); 559 kfree(lw);
549 return true; 560 return true;
@@ -648,13 +659,6 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
648 if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK) 659 if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
649 return false; 660 return false;
650 661
651 if (rsp->sync_hdr.CreditRequest) {
652 spin_lock(&server->req_lock);
653 server->credits += le16_to_cpu(rsp->sync_hdr.CreditRequest);
654 spin_unlock(&server->req_lock);
655 wake_up(&server->request_q);
656 }
657
658 if (rsp->StructureSize != 662 if (rsp->StructureSize !=
659 smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) { 663 smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
660 if (le16_to_cpu(rsp->StructureSize) == 44) 664 if (le16_to_cpu(rsp->StructureSize) == 44)
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 6f96e2292856..085e91436da7 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -67,10 +67,13 @@ change_conf(struct TCP_Server_Info *server)
67} 67}
68 68
69static void 69static void
70smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add, 70smb2_add_credits(struct TCP_Server_Info *server,
71 const int optype) 71 const struct cifs_credits *credits, const int optype)
72{ 72{
73 int *val, rc = -1; 73 int *val, rc = -1;
74 unsigned int add = credits->value;
75 unsigned int instance = credits->instance;
76 bool reconnect_detected = false;
74 77
75 spin_lock(&server->req_lock); 78 spin_lock(&server->req_lock);
76 val = server->ops->get_credits_field(server, optype); 79 val = server->ops->get_credits_field(server, optype);
@@ -79,8 +82,11 @@ smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
79 if (((optype & CIFS_OP_MASK) == CIFS_NEG_OP) && (*val != 0)) 82 if (((optype & CIFS_OP_MASK) == CIFS_NEG_OP) && (*val != 0))
80 trace_smb3_reconnect_with_invalid_credits(server->CurrentMid, 83 trace_smb3_reconnect_with_invalid_credits(server->CurrentMid,
81 server->hostname, *val); 84 server->hostname, *val);
85 if ((instance == 0) || (instance == server->reconnect_instance))
86 *val += add;
87 else
88 reconnect_detected = true;
82 89
83 *val += add;
84 if (*val > 65000) { 90 if (*val > 65000) {
85 *val = 65000; /* Don't get near 64K credits, avoid srv bugs */ 91 *val = 65000; /* Don't get near 64K credits, avoid srv bugs */
86 printk_once(KERN_WARNING "server overflowed SMB3 credits\n"); 92 printk_once(KERN_WARNING "server overflowed SMB3 credits\n");
@@ -102,7 +108,12 @@ smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
102 spin_unlock(&server->req_lock); 108 spin_unlock(&server->req_lock);
103 wake_up(&server->request_q); 109 wake_up(&server->request_q);
104 110
105 if (server->tcpStatus == CifsNeedReconnect) 111 if (reconnect_detected)
112 cifs_dbg(FYI, "trying to put %d credits from the old server instance %d\n",
113 add, instance);
114
115 if (server->tcpStatus == CifsNeedReconnect
116 || server->tcpStatus == CifsExiting)
106 return; 117 return;
107 118
108 switch (rc) { 119 switch (rc) {
@@ -163,7 +174,7 @@ smb2_get_credits(struct mid_q_entry *mid)
163 174
164static int 175static int
165smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, 176smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
166 unsigned int *num, unsigned int *credits) 177 unsigned int *num, struct cifs_credits *credits)
167{ 178{
168 int rc = 0; 179 int rc = 0;
169 unsigned int scredits; 180 unsigned int scredits;
@@ -189,7 +200,8 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
189 /* can deadlock with reopen */ 200 /* can deadlock with reopen */
190 if (scredits <= 8) { 201 if (scredits <= 8) {
191 *num = SMB2_MAX_BUFFER_SIZE; 202 *num = SMB2_MAX_BUFFER_SIZE;
192 *credits = 0; 203 credits->value = 0;
204 credits->instance = 0;
193 break; 205 break;
194 } 206 }
195 207
@@ -198,8 +210,10 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
198 *num = min_t(unsigned int, size, 210 *num = min_t(unsigned int, size,
199 scredits * SMB2_MAX_BUFFER_SIZE); 211 scredits * SMB2_MAX_BUFFER_SIZE);
200 212
201 *credits = DIV_ROUND_UP(*num, SMB2_MAX_BUFFER_SIZE); 213 credits->value =
202 server->credits -= *credits; 214 DIV_ROUND_UP(*num, SMB2_MAX_BUFFER_SIZE);
215 credits->instance = server->reconnect_instance;
216 server->credits -= credits->value;
203 server->in_flight++; 217 server->in_flight++;
204 break; 218 break;
205 } 219 }
@@ -208,6 +222,38 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
208 return rc; 222 return rc;
209} 223}
210 224
225static int
226smb2_adjust_credits(struct TCP_Server_Info *server,
227 struct cifs_credits *credits,
228 const unsigned int payload_size)
229{
230 int new_val = DIV_ROUND_UP(payload_size, SMB2_MAX_BUFFER_SIZE);
231
232 if (!credits->value || credits->value == new_val)
233 return 0;
234
235 if (credits->value < new_val) {
236 WARN_ONCE(1, "request has less credits (%d) than required (%d)",
237 credits->value, new_val);
238 return -ENOTSUPP;
239 }
240
241 spin_lock(&server->req_lock);
242
243 if (server->reconnect_instance != credits->instance) {
244 spin_unlock(&server->req_lock);
245 cifs_dbg(VFS, "trying to return %d credits to old session\n",
246 credits->value - new_val);
247 return -EAGAIN;
248 }
249
250 server->credits += credits->value - new_val;
251 spin_unlock(&server->req_lock);
252 wake_up(&server->request_q);
253 credits->value = new_val;
254 return 0;
255}
256
211static __u64 257static __u64
212smb2_get_next_mid(struct TCP_Server_Info *server) 258smb2_get_next_mid(struct TCP_Server_Info *server)
213{ 259{
@@ -219,6 +265,15 @@ smb2_get_next_mid(struct TCP_Server_Info *server)
219 return mid; 265 return mid;
220} 266}
221 267
268static void
269smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
270{
271 spin_lock(&GlobalMid_Lock);
272 if (server->CurrentMid >= val)
273 server->CurrentMid -= val;
274 spin_unlock(&GlobalMid_Lock);
275}
276
222static struct mid_q_entry * 277static struct mid_q_entry *
223smb2_find_mid(struct TCP_Server_Info *server, char *buf) 278smb2_find_mid(struct TCP_Server_Info *server, char *buf)
224{ 279{
@@ -940,6 +995,16 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
940 resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; 995 resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
941 memset(rsp_iov, 0, sizeof(rsp_iov)); 996 memset(rsp_iov, 0, sizeof(rsp_iov));
942 997
998 if (ses->server->ops->query_all_EAs) {
999 if (!ea_value) {
1000 rc = ses->server->ops->query_all_EAs(xid, tcon, path,
1001 ea_name, NULL, 0,
1002 cifs_sb);
1003 if (rc == -ENODATA)
1004 goto sea_exit;
1005 }
1006 }
1007
943 /* Open */ 1008 /* Open */
944 memset(&open_iov, 0, sizeof(open_iov)); 1009 memset(&open_iov, 0, sizeof(open_iov));
945 rqst[0].rq_iov = open_iov; 1010 rqst[0].rq_iov = open_iov;
@@ -1753,14 +1818,14 @@ smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
1753* the number of credits and return true. Otherwise - return false. 1818* the number of credits and return true. Otherwise - return false.
1754*/ 1819*/
1755static bool 1820static bool
1756smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length) 1821smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
1757{ 1822{
1758 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf; 1823 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
1759 1824
1760 if (shdr->Status != STATUS_PENDING) 1825 if (shdr->Status != STATUS_PENDING)
1761 return false; 1826 return false;
1762 1827
1763 if (!length) { 1828 if (shdr->CreditRequest) {
1764 spin_lock(&server->req_lock); 1829 spin_lock(&server->req_lock);
1765 server->credits += le16_to_cpu(shdr->CreditRequest); 1830 server->credits += le16_to_cpu(shdr->CreditRequest);
1766 spin_unlock(&server->req_lock); 1831 spin_unlock(&server->req_lock);
@@ -2595,6 +2660,15 @@ smb2_downgrade_oplock(struct TCP_Server_Info *server,
2595} 2660}
2596 2661
2597static void 2662static void
2663smb21_downgrade_oplock(struct TCP_Server_Info *server,
2664 struct cifsInodeInfo *cinode, bool set_level2)
2665{
2666 server->ops->set_oplock_level(cinode,
2667 set_level2 ? SMB2_LEASE_READ_CACHING_HE :
2668 0, 0, NULL);
2669}
2670
2671static void
2598smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, 2672smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
2599 unsigned int epoch, bool *purge_cache) 2673 unsigned int epoch, bool *purge_cache)
2600{ 2674{
@@ -3210,15 +3284,15 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
3210 } 3284 }
3211 3285
3212 if (server->ops->is_status_pending && 3286 if (server->ops->is_status_pending &&
3213 server->ops->is_status_pending(buf, server, 0)) 3287 server->ops->is_status_pending(buf, server))
3214 return -1; 3288 return -1;
3215 3289
3216 /* set up first two iov to get credits */ 3290 /* set up first two iov to get credits */
3217 rdata->iov[0].iov_base = buf; 3291 rdata->iov[0].iov_base = buf;
3218 rdata->iov[0].iov_len = 4; 3292 rdata->iov[0].iov_len = 0;
3219 rdata->iov[1].iov_base = buf + 4; 3293 rdata->iov[1].iov_base = buf;
3220 rdata->iov[1].iov_len = 3294 rdata->iov[1].iov_len =
3221 min_t(unsigned int, buf_len, server->vals->read_rsp_size) - 4; 3295 min_t(unsigned int, buf_len, server->vals->read_rsp_size);
3222 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n", 3296 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
3223 rdata->iov[0].iov_base, rdata->iov[0].iov_len); 3297 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
3224 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n", 3298 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
@@ -3541,6 +3615,7 @@ struct smb_version_operations smb20_operations = {
3541 .get_credits = smb2_get_credits, 3615 .get_credits = smb2_get_credits,
3542 .wait_mtu_credits = cifs_wait_mtu_credits, 3616 .wait_mtu_credits = cifs_wait_mtu_credits,
3543 .get_next_mid = smb2_get_next_mid, 3617 .get_next_mid = smb2_get_next_mid,
3618 .revert_current_mid = smb2_revert_current_mid,
3544 .read_data_offset = smb2_read_data_offset, 3619 .read_data_offset = smb2_read_data_offset,
3545 .read_data_length = smb2_read_data_length, 3620 .read_data_length = smb2_read_data_length,
3546 .map_error = map_smb2_to_linux_error, 3621 .map_error = map_smb2_to_linux_error,
@@ -3635,7 +3710,9 @@ struct smb_version_operations smb21_operations = {
3635 .get_credits_field = smb2_get_credits_field, 3710 .get_credits_field = smb2_get_credits_field,
3636 .get_credits = smb2_get_credits, 3711 .get_credits = smb2_get_credits,
3637 .wait_mtu_credits = smb2_wait_mtu_credits, 3712 .wait_mtu_credits = smb2_wait_mtu_credits,
3713 .adjust_credits = smb2_adjust_credits,
3638 .get_next_mid = smb2_get_next_mid, 3714 .get_next_mid = smb2_get_next_mid,
3715 .revert_current_mid = smb2_revert_current_mid,
3639 .read_data_offset = smb2_read_data_offset, 3716 .read_data_offset = smb2_read_data_offset,
3640 .read_data_length = smb2_read_data_length, 3717 .read_data_length = smb2_read_data_length,
3641 .map_error = map_smb2_to_linux_error, 3718 .map_error = map_smb2_to_linux_error,
@@ -3646,7 +3723,7 @@ struct smb_version_operations smb21_operations = {
3646 .print_stats = smb2_print_stats, 3723 .print_stats = smb2_print_stats,
3647 .is_oplock_break = smb2_is_valid_oplock_break, 3724 .is_oplock_break = smb2_is_valid_oplock_break,
3648 .handle_cancelled_mid = smb2_handle_cancelled_mid, 3725 .handle_cancelled_mid = smb2_handle_cancelled_mid,
3649 .downgrade_oplock = smb2_downgrade_oplock, 3726 .downgrade_oplock = smb21_downgrade_oplock,
3650 .need_neg = smb2_need_neg, 3727 .need_neg = smb2_need_neg,
3651 .negotiate = smb2_negotiate, 3728 .negotiate = smb2_negotiate,
3652 .negotiate_wsize = smb2_negotiate_wsize, 3729 .negotiate_wsize = smb2_negotiate_wsize,
@@ -3731,7 +3808,9 @@ struct smb_version_operations smb30_operations = {
3731 .get_credits_field = smb2_get_credits_field, 3808 .get_credits_field = smb2_get_credits_field,
3732 .get_credits = smb2_get_credits, 3809 .get_credits = smb2_get_credits,
3733 .wait_mtu_credits = smb2_wait_mtu_credits, 3810 .wait_mtu_credits = smb2_wait_mtu_credits,
3811 .adjust_credits = smb2_adjust_credits,
3734 .get_next_mid = smb2_get_next_mid, 3812 .get_next_mid = smb2_get_next_mid,
3813 .revert_current_mid = smb2_revert_current_mid,
3735 .read_data_offset = smb2_read_data_offset, 3814 .read_data_offset = smb2_read_data_offset,
3736 .read_data_length = smb2_read_data_length, 3815 .read_data_length = smb2_read_data_length,
3737 .map_error = map_smb2_to_linux_error, 3816 .map_error = map_smb2_to_linux_error,
@@ -3743,7 +3822,7 @@ struct smb_version_operations smb30_operations = {
3743 .dump_share_caps = smb2_dump_share_caps, 3822 .dump_share_caps = smb2_dump_share_caps,
3744 .is_oplock_break = smb2_is_valid_oplock_break, 3823 .is_oplock_break = smb2_is_valid_oplock_break,
3745 .handle_cancelled_mid = smb2_handle_cancelled_mid, 3824 .handle_cancelled_mid = smb2_handle_cancelled_mid,
3746 .downgrade_oplock = smb2_downgrade_oplock, 3825 .downgrade_oplock = smb21_downgrade_oplock,
3747 .need_neg = smb2_need_neg, 3826 .need_neg = smb2_need_neg,
3748 .negotiate = smb2_negotiate, 3827 .negotiate = smb2_negotiate,
3749 .negotiate_wsize = smb3_negotiate_wsize, 3828 .negotiate_wsize = smb3_negotiate_wsize,
@@ -3836,7 +3915,9 @@ struct smb_version_operations smb311_operations = {
3836 .get_credits_field = smb2_get_credits_field, 3915 .get_credits_field = smb2_get_credits_field,
3837 .get_credits = smb2_get_credits, 3916 .get_credits = smb2_get_credits,
3838 .wait_mtu_credits = smb2_wait_mtu_credits, 3917 .wait_mtu_credits = smb2_wait_mtu_credits,
3918 .adjust_credits = smb2_adjust_credits,
3839 .get_next_mid = smb2_get_next_mid, 3919 .get_next_mid = smb2_get_next_mid,
3920 .revert_current_mid = smb2_revert_current_mid,
3840 .read_data_offset = smb2_read_data_offset, 3921 .read_data_offset = smb2_read_data_offset,
3841 .read_data_length = smb2_read_data_length, 3922 .read_data_length = smb2_read_data_length,
3842 .map_error = map_smb2_to_linux_error, 3923 .map_error = map_smb2_to_linux_error,
@@ -3848,7 +3929,7 @@ struct smb_version_operations smb311_operations = {
3848 .dump_share_caps = smb2_dump_share_caps, 3929 .dump_share_caps = smb2_dump_share_caps,
3849 .is_oplock_break = smb2_is_valid_oplock_break, 3930 .is_oplock_break = smb2_is_valid_oplock_break,
3850 .handle_cancelled_mid = smb2_handle_cancelled_mid, 3931 .handle_cancelled_mid = smb2_handle_cancelled_mid,
3851 .downgrade_oplock = smb2_downgrade_oplock, 3932 .downgrade_oplock = smb21_downgrade_oplock,
3852 .need_neg = smb2_need_neg, 3933 .need_neg = smb2_need_neg,
3853 .negotiate = smb2_negotiate, 3934 .negotiate = smb2_negotiate,
3854 .negotiate_wsize = smb3_negotiate_wsize, 3935 .negotiate_wsize = smb3_negotiate_wsize,
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 77b3aaa39b35..60fbe306f604 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -107,13 +107,13 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd,
107 struct TCP_Server_Info *server = tcon->ses->server; 107 struct TCP_Server_Info *server = tcon->ses->server;
108 108
109 spin_lock(&server->req_lock); 109 spin_lock(&server->req_lock);
110 /* Request up to 2 credits but don't go over the limit. */ 110 /* Request up to 10 credits but don't go over the limit. */
111 if (server->credits >= server->max_credits) 111 if (server->credits >= server->max_credits)
112 shdr->CreditRequest = cpu_to_le16(0); 112 shdr->CreditRequest = cpu_to_le16(0);
113 else 113 else
114 shdr->CreditRequest = cpu_to_le16( 114 shdr->CreditRequest = cpu_to_le16(
115 min_t(int, server->max_credits - 115 min_t(int, server->max_credits -
116 server->credits, 2)); 116 server->credits, 10));
117 spin_unlock(&server->req_lock); 117 spin_unlock(&server->req_lock);
118 } else { 118 } else {
119 shdr->CreditRequest = cpu_to_le16(2); 119 shdr->CreditRequest = cpu_to_le16(2);
@@ -173,8 +173,8 @@ static int __smb2_reconnect(const struct nls_table *nlsc,
173 return -ENOMEM; 173 return -ENOMEM;
174 174
175 if (tcon->ipc) { 175 if (tcon->ipc) {
176 snprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", 176 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
177 tcon->ses->server->hostname); 177 tcon->ses->server->hostname);
178 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); 178 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
179 goto out; 179 goto out;
180 } 180 }
@@ -206,7 +206,7 @@ static int __smb2_reconnect(const struct nls_table *nlsc,
206 continue; 206 continue;
207 } 207 }
208 208
209 snprintf(tree, MAX_TREE_SIZE, "\\%s", tgt); 209 scnprintf(tree, MAX_TREE_SIZE, "\\%s", tgt);
210 210
211 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); 211 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
212 if (!rc) 212 if (!rc)
@@ -490,6 +490,23 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
490{ 490{
491 pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE; 491 pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
492 pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN); 492 pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
493 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
494 pneg_ctxt->Name[0] = 0x93;
495 pneg_ctxt->Name[1] = 0xAD;
496 pneg_ctxt->Name[2] = 0x25;
497 pneg_ctxt->Name[3] = 0x50;
498 pneg_ctxt->Name[4] = 0x9C;
499 pneg_ctxt->Name[5] = 0xB4;
500 pneg_ctxt->Name[6] = 0x11;
501 pneg_ctxt->Name[7] = 0xE7;
502 pneg_ctxt->Name[8] = 0xB4;
503 pneg_ctxt->Name[9] = 0x23;
504 pneg_ctxt->Name[10] = 0x83;
505 pneg_ctxt->Name[11] = 0xDE;
506 pneg_ctxt->Name[12] = 0x96;
507 pneg_ctxt->Name[13] = 0x8B;
508 pneg_ctxt->Name[14] = 0xCD;
509 pneg_ctxt->Name[15] = 0x7C;
493} 510}
494 511
495static void 512static void
@@ -986,8 +1003,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
986 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 1003 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
987 FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, 1004 FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
988 (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen); 1005 (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen);
989 1006 if (rc == -EOPNOTSUPP) {
990 if (rc != 0) { 1007 /*
1008 * Old Windows versions or Netapp SMB server can return
1009 * not supported error. Client should accept it.
1010 */
1011 cifs_dbg(VFS, "Server does not support validate negotiate\n");
1012 return 0;
1013 } else if (rc != 0) {
991 cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); 1014 cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc);
992 rc = -EIO; 1015 rc = -EIO;
993 goto out_free_inbuf; 1016 goto out_free_inbuf;
@@ -1614,6 +1637,9 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
1614 rqst.rq_iov = iov; 1637 rqst.rq_iov = iov;
1615 rqst.rq_nvec = 2; 1638 rqst.rq_nvec = 2;
1616 1639
1640 /* Need 64 for max size write so ask for more in case not there yet */
1641 req->sync_hdr.CreditRequest = cpu_to_le16(64);
1642
1617 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 1643 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
1618 cifs_small_buf_release(req); 1644 cifs_small_buf_release(req);
1619 rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; 1645 rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base;
@@ -2170,6 +2196,8 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
2170 rqst.rq_iov = iov; 2196 rqst.rq_iov = iov;
2171 rqst.rq_nvec = n_iov; 2197 rqst.rq_nvec = n_iov;
2172 2198
2199 trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE,
2200 FILE_WRITE_ATTRIBUTES);
2173 /* resource #4: response buffer */ 2201 /* resource #4: response buffer */
2174 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2202 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
2175 if (rc) { 2203 if (rc) {
@@ -2388,6 +2416,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2388 if (rc) 2416 if (rc)
2389 goto creat_exit; 2417 goto creat_exit;
2390 2418
2419 trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid,
2420 oparms->create_options, oparms->desired_access);
2421
2391 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, 2422 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
2392 &rsp_iov); 2423 &rsp_iov);
2393 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; 2424 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
@@ -2837,6 +2868,9 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
2837 if (rc) 2868 if (rc)
2838 goto qinf_exit; 2869 goto qinf_exit;
2839 2870
2871 trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid,
2872 ses->Suid, info_class, (__u32)info_type);
2873
2840 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2874 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
2841 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; 2875 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
2842 2876
@@ -2847,6 +2881,9 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
2847 goto qinf_exit; 2881 goto qinf_exit;
2848 } 2882 }
2849 2883
2884 trace_smb3_query_info_done(xid, persistent_fid, tcon->tid,
2885 ses->Suid, info_class, (__u32)info_type);
2886
2850 if (dlen) { 2887 if (dlen) {
2851 *dlen = le32_to_cpu(rsp->OutputBufferLength); 2888 *dlen = le32_to_cpu(rsp->OutputBufferLength);
2852 if (!*data) { 2889 if (!*data) {
@@ -2924,14 +2961,16 @@ smb2_echo_callback(struct mid_q_entry *mid)
2924{ 2961{
2925 struct TCP_Server_Info *server = mid->callback_data; 2962 struct TCP_Server_Info *server = mid->callback_data;
2926 struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf; 2963 struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
2927 unsigned int credits_received = 0; 2964 struct cifs_credits credits = { .value = 0, .instance = 0 };
2928 2965
2929 if (mid->mid_state == MID_RESPONSE_RECEIVED 2966 if (mid->mid_state == MID_RESPONSE_RECEIVED
2930 || mid->mid_state == MID_RESPONSE_MALFORMED) 2967 || mid->mid_state == MID_RESPONSE_MALFORMED) {
2931 credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); 2968 credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
2969 credits.instance = server->reconnect_instance;
2970 }
2932 2971
2933 DeleteMidQEntry(mid); 2972 DeleteMidQEntry(mid);
2934 add_credits(server, credits_received, CIFS_ECHO_OP); 2973 add_credits(server, &credits, CIFS_ECHO_OP);
2935} 2974}
2936 2975
2937void smb2_reconnect_server(struct work_struct *work) 2976void smb2_reconnect_server(struct work_struct *work)
@@ -3023,7 +3062,7 @@ SMB2_echo(struct TCP_Server_Info *server)
3023 iov[0].iov_base = (char *)req; 3062 iov[0].iov_base = (char *)req;
3024 3063
3025 rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL, 3064 rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL,
3026 server, CIFS_ECHO_OP); 3065 server, CIFS_ECHO_OP, NULL);
3027 if (rc) 3066 if (rc)
3028 cifs_dbg(FYI, "Echo request failed: %d\n", rc); 3067 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
3029 3068
@@ -3114,6 +3153,11 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
3114 req->MinimumCount = 0; 3153 req->MinimumCount = 0;
3115 req->Length = cpu_to_le32(io_parms->length); 3154 req->Length = cpu_to_le32(io_parms->length);
3116 req->Offset = cpu_to_le64(io_parms->offset); 3155 req->Offset = cpu_to_le64(io_parms->offset);
3156
3157 trace_smb3_read_enter(0 /* xid */,
3158 io_parms->persistent_fid,
3159 io_parms->tcon->tid, io_parms->tcon->ses->Suid,
3160 io_parms->offset, io_parms->length);
3117#ifdef CONFIG_CIFS_SMB_DIRECT 3161#ifdef CONFIG_CIFS_SMB_DIRECT
3118 /* 3162 /*
3119 * If we want to do a RDMA write, fill in and append 3163 * If we want to do a RDMA write, fill in and append
@@ -3184,7 +3228,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
3184 struct TCP_Server_Info *server = tcon->ses->server; 3228 struct TCP_Server_Info *server = tcon->ses->server;
3185 struct smb2_sync_hdr *shdr = 3229 struct smb2_sync_hdr *shdr =
3186 (struct smb2_sync_hdr *)rdata->iov[0].iov_base; 3230 (struct smb2_sync_hdr *)rdata->iov[0].iov_base;
3187 unsigned int credits_received = 0; 3231 struct cifs_credits credits = { .value = 0, .instance = 0 };
3188 struct smb_rqst rqst = { .rq_iov = rdata->iov, 3232 struct smb_rqst rqst = { .rq_iov = rdata->iov,
3189 .rq_nvec = 2, 3233 .rq_nvec = 2,
3190 .rq_pages = rdata->pages, 3234 .rq_pages = rdata->pages,
@@ -3199,7 +3243,8 @@ smb2_readv_callback(struct mid_q_entry *mid)
3199 3243
3200 switch (mid->mid_state) { 3244 switch (mid->mid_state) {
3201 case MID_RESPONSE_RECEIVED: 3245 case MID_RESPONSE_RECEIVED:
3202 credits_received = le16_to_cpu(shdr->CreditRequest); 3246 credits.value = le16_to_cpu(shdr->CreditRequest);
3247 credits.instance = server->reconnect_instance;
3203 /* result already set, check signature */ 3248 /* result already set, check signature */
3204 if (server->sign && !mid->decrypted) { 3249 if (server->sign && !mid->decrypted) {
3205 int rc; 3250 int rc;
@@ -3224,11 +3269,11 @@ smb2_readv_callback(struct mid_q_entry *mid)
3224 cifs_stats_bytes_read(tcon, rdata->got_bytes); 3269 cifs_stats_bytes_read(tcon, rdata->got_bytes);
3225 break; 3270 break;
3226 case MID_RESPONSE_MALFORMED: 3271 case MID_RESPONSE_MALFORMED:
3227 credits_received = le16_to_cpu(shdr->CreditRequest); 3272 credits.value = le16_to_cpu(shdr->CreditRequest);
3273 credits.instance = server->reconnect_instance;
3228 /* fall through */ 3274 /* fall through */
3229 default: 3275 default:
3230 if (rdata->result != -ENODATA) 3276 rdata->result = -EIO;
3231 rdata->result = -EIO;
3232 } 3277 }
3233#ifdef CONFIG_CIFS_SMB_DIRECT 3278#ifdef CONFIG_CIFS_SMB_DIRECT
3234 /* 3279 /*
@@ -3255,7 +3300,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
3255 3300
3256 queue_work(cifsiod_wq, &rdata->work); 3301 queue_work(cifsiod_wq, &rdata->work);
3257 DeleteMidQEntry(mid); 3302 DeleteMidQEntry(mid);
3258 add_credits(server, credits_received, 0); 3303 add_credits(server, &credits, 0);
3259} 3304}
3260 3305
3261/* smb2_async_readv - send an async read, and set up mid to handle result */ 3306/* smb2_async_readv - send an async read, and set up mid to handle result */
@@ -3285,17 +3330,8 @@ smb2_async_readv(struct cifs_readdata *rdata)
3285 3330
3286 rc = smb2_new_read_req( 3331 rc = smb2_new_read_req(
3287 (void **) &buf, &total_len, &io_parms, rdata, 0, 0); 3332 (void **) &buf, &total_len, &io_parms, rdata, 0, 0);
3288 if (rc) { 3333 if (rc)
3289 if (rc == -EAGAIN && rdata->credits) {
3290 /* credits was reset by reconnect */
3291 rdata->credits = 0;
3292 /* reduce in_flight value since we won't send the req */
3293 spin_lock(&server->req_lock);
3294 server->in_flight--;
3295 spin_unlock(&server->req_lock);
3296 }
3297 return rc; 3334 return rc;
3298 }
3299 3335
3300 if (smb3_encryption_required(io_parms.tcon)) 3336 if (smb3_encryption_required(io_parms.tcon))
3301 flags |= CIFS_TRANSFORM_REQ; 3337 flags |= CIFS_TRANSFORM_REQ;
@@ -3305,24 +3341,24 @@ smb2_async_readv(struct cifs_readdata *rdata)
3305 3341
3306 shdr = (struct smb2_sync_hdr *)buf; 3342 shdr = (struct smb2_sync_hdr *)buf;
3307 3343
3308 if (rdata->credits) { 3344 if (rdata->credits.value > 0) {
3309 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, 3345 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
3310 SMB2_MAX_BUFFER_SIZE)); 3346 SMB2_MAX_BUFFER_SIZE));
3311 shdr->CreditRequest = 3347 shdr->CreditRequest =
3312 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); 3348 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
3313 spin_lock(&server->req_lock); 3349
3314 server->credits += rdata->credits - 3350 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
3315 le16_to_cpu(shdr->CreditCharge); 3351 if (rc)
3316 spin_unlock(&server->req_lock); 3352 goto async_readv_out;
3317 wake_up(&server->request_q); 3353
3318 rdata->credits = le16_to_cpu(shdr->CreditCharge);
3319 flags |= CIFS_HAS_CREDITS; 3354 flags |= CIFS_HAS_CREDITS;
3320 } 3355 }
3321 3356
3322 kref_get(&rdata->refcount); 3357 kref_get(&rdata->refcount);
3323 rc = cifs_call_async(io_parms.tcon->ses->server, &rqst, 3358 rc = cifs_call_async(io_parms.tcon->ses->server, &rqst,
3324 cifs_readv_receive, smb2_readv_callback, 3359 cifs_readv_receive, smb2_readv_callback,
3325 smb3_handle_read_data, rdata, flags); 3360 smb3_handle_read_data, rdata, flags,
3361 &rdata->credits);
3326 if (rc) { 3362 if (rc) {
3327 kref_put(&rdata->refcount, cifs_readdata_release); 3363 kref_put(&rdata->refcount, cifs_readdata_release);
3328 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE); 3364 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
@@ -3332,6 +3368,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
3332 io_parms.offset, io_parms.length, rc); 3368 io_parms.offset, io_parms.length, rc);
3333 } 3369 }
3334 3370
3371async_readv_out:
3335 cifs_small_buf_release(buf); 3372 cifs_small_buf_release(buf);
3336 return rc; 3373 return rc;
3337} 3374}
@@ -3378,7 +3415,10 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
3378 io_parms->tcon->tid, ses->Suid, 3415 io_parms->tcon->tid, ses->Suid,
3379 io_parms->offset, io_parms->length, 3416 io_parms->offset, io_parms->length,
3380 rc); 3417 rc);
3381 } 3418 } else
3419 trace_smb3_read_done(xid, req->PersistentFileId,
3420 io_parms->tcon->tid, ses->Suid,
3421 io_parms->offset, 0);
3382 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 3422 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
3383 return rc == -ENODATA ? 0 : rc; 3423 return rc == -ENODATA ? 0 : rc;
3384 } else 3424 } else
@@ -3417,14 +3457,16 @@ smb2_writev_callback(struct mid_q_entry *mid)
3417{ 3457{
3418 struct cifs_writedata *wdata = mid->callback_data; 3458 struct cifs_writedata *wdata = mid->callback_data;
3419 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); 3459 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
3460 struct TCP_Server_Info *server = tcon->ses->server;
3420 unsigned int written; 3461 unsigned int written;
3421 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf; 3462 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
3422 unsigned int credits_received = 0; 3463 struct cifs_credits credits = { .value = 0, .instance = 0 };
3423 3464
3424 switch (mid->mid_state) { 3465 switch (mid->mid_state) {
3425 case MID_RESPONSE_RECEIVED: 3466 case MID_RESPONSE_RECEIVED:
3426 credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); 3467 credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3427 wdata->result = smb2_check_receive(mid, tcon->ses->server, 0); 3468 credits.instance = server->reconnect_instance;
3469 wdata->result = smb2_check_receive(mid, server, 0);
3428 if (wdata->result != 0) 3470 if (wdata->result != 0)
3429 break; 3471 break;
3430 3472
@@ -3448,7 +3490,8 @@ smb2_writev_callback(struct mid_q_entry *mid)
3448 wdata->result = -EAGAIN; 3490 wdata->result = -EAGAIN;
3449 break; 3491 break;
3450 case MID_RESPONSE_MALFORMED: 3492 case MID_RESPONSE_MALFORMED:
3451 credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); 3493 credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3494 credits.instance = server->reconnect_instance;
3452 /* fall through */ 3495 /* fall through */
3453 default: 3496 default:
3454 wdata->result = -EIO; 3497 wdata->result = -EIO;
@@ -3481,7 +3524,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
3481 3524
3482 queue_work(cifsiod_wq, &wdata->work); 3525 queue_work(cifsiod_wq, &wdata->work);
3483 DeleteMidQEntry(mid); 3526 DeleteMidQEntry(mid);
3484 add_credits(tcon->ses->server, credits_received, 0); 3527 add_credits(server, &credits, 0);
3485} 3528}
3486 3529
3487/* smb2_async_writev - send an async write, and set up mid to handle result */ 3530/* smb2_async_writev - send an async write, and set up mid to handle result */
@@ -3499,17 +3542,8 @@ smb2_async_writev(struct cifs_writedata *wdata,
3499 unsigned int total_len; 3542 unsigned int total_len;
3500 3543
3501 rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len); 3544 rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len);
3502 if (rc) { 3545 if (rc)
3503 if (rc == -EAGAIN && wdata->credits) { 3546 return rc;
3504 /* credits was reset by reconnect */
3505 wdata->credits = 0;
3506 /* reduce in_flight value since we won't send the req */
3507 spin_lock(&server->req_lock);
3508 server->in_flight--;
3509 spin_unlock(&server->req_lock);
3510 }
3511 goto async_writev_out;
3512 }
3513 3547
3514 if (smb3_encryption_required(tcon)) 3548 if (smb3_encryption_required(tcon))
3515 flags |= CIFS_TRANSFORM_REQ; 3549 flags |= CIFS_TRANSFORM_REQ;
@@ -3526,6 +3560,9 @@ smb2_async_writev(struct cifs_writedata *wdata,
3526 req->DataOffset = cpu_to_le16( 3560 req->DataOffset = cpu_to_le16(
3527 offsetof(struct smb2_write_req, Buffer)); 3561 offsetof(struct smb2_write_req, Buffer));
3528 req->RemainingBytes = 0; 3562 req->RemainingBytes = 0;
3563
3564 trace_smb3_write_enter(0 /* xid */, wdata->cfile->fid.persistent_fid,
3565 tcon->tid, tcon->ses->Suid, wdata->offset, wdata->bytes);
3529#ifdef CONFIG_CIFS_SMB_DIRECT 3566#ifdef CONFIG_CIFS_SMB_DIRECT
3530 /* 3567 /*
3531 * If we want to do a server RDMA read, fill in and append 3568 * If we want to do a server RDMA read, fill in and append
@@ -3595,23 +3632,22 @@ smb2_async_writev(struct cifs_writedata *wdata,
3595 req->Length = cpu_to_le32(wdata->bytes); 3632 req->Length = cpu_to_le32(wdata->bytes);
3596#endif 3633#endif
3597 3634
3598 if (wdata->credits) { 3635 if (wdata->credits.value > 0) {
3599 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, 3636 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
3600 SMB2_MAX_BUFFER_SIZE)); 3637 SMB2_MAX_BUFFER_SIZE));
3601 shdr->CreditRequest = 3638 shdr->CreditRequest =
3602 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); 3639 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
3603 spin_lock(&server->req_lock); 3640
3604 server->credits += wdata->credits - 3641 rc = adjust_credits(server, &wdata->credits, wdata->bytes);
3605 le16_to_cpu(shdr->CreditCharge); 3642 if (rc)
3606 spin_unlock(&server->req_lock); 3643 goto async_writev_out;
3607 wake_up(&server->request_q); 3644
3608 wdata->credits = le16_to_cpu(shdr->CreditCharge);
3609 flags |= CIFS_HAS_CREDITS; 3645 flags |= CIFS_HAS_CREDITS;
3610 } 3646 }
3611 3647
3612 kref_get(&wdata->refcount); 3648 kref_get(&wdata->refcount);
3613 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL, 3649 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
3614 wdata, flags); 3650 wdata, flags, &wdata->credits);
3615 3651
3616 if (rc) { 3652 if (rc) {
3617 trace_smb3_write_err(0 /* no xid */, req->PersistentFileId, 3653 trace_smb3_write_err(0 /* no xid */, req->PersistentFileId,
@@ -3674,6 +3710,10 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
3674 offsetof(struct smb2_write_req, Buffer)); 3710 offsetof(struct smb2_write_req, Buffer));
3675 req->RemainingBytes = 0; 3711 req->RemainingBytes = 0;
3676 3712
3713 trace_smb3_write_enter(xid, io_parms->persistent_fid,
3714 io_parms->tcon->tid, io_parms->tcon->ses->Suid,
3715 io_parms->offset, io_parms->length);
3716
3677 iov[0].iov_base = (char *)req; 3717 iov[0].iov_base = (char *)req;
3678 /* 1 for Buffer */ 3718 /* 1 for Buffer */
3679 iov[0].iov_len = total_len - 1; 3719 iov[0].iov_len = total_len - 1;
@@ -3836,6 +3876,9 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3836 rqst.rq_iov = iov; 3876 rqst.rq_iov = iov;
3837 rqst.rq_nvec = 2; 3877 rqst.rq_nvec = 2;
3838 3878
3879 trace_smb3_query_dir_enter(xid, persistent_fid, tcon->tid,
3880 tcon->ses->Suid, index, output_size);
3881
3839 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 3882 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
3840 cifs_small_buf_release(req); 3883 cifs_small_buf_release(req);
3841 rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base; 3884 rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
@@ -3843,18 +3886,26 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3843 if (rc) { 3886 if (rc) {
3844 if (rc == -ENODATA && 3887 if (rc == -ENODATA &&
3845 rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { 3888 rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
3889 trace_smb3_query_dir_done(xid, persistent_fid,
3890 tcon->tid, tcon->ses->Suid, index, 0);
3846 srch_inf->endOfSearch = true; 3891 srch_inf->endOfSearch = true;
3847 rc = 0; 3892 rc = 0;
3848 } else 3893 } else {
3894 trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
3895 tcon->ses->Suid, index, 0, rc);
3849 cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); 3896 cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
3897 }
3850 goto qdir_exit; 3898 goto qdir_exit;
3851 } 3899 }
3852 3900
3853 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 3901 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
3854 le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 3902 le32_to_cpu(rsp->OutputBufferLength), &rsp_iov,
3855 info_buf_size); 3903 info_buf_size);
3856 if (rc) 3904 if (rc) {
3905 trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
3906 tcon->ses->Suid, index, 0, rc);
3857 goto qdir_exit; 3907 goto qdir_exit;
3908 }
3858 3909
3859 srch_inf->unicode = true; 3910 srch_inf->unicode = true;
3860 3911
@@ -3882,6 +3933,8 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3882 else 3933 else
3883 cifs_dbg(VFS, "illegal search buffer type\n"); 3934 cifs_dbg(VFS, "illegal search buffer type\n");
3884 3935
3936 trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid,
3937 tcon->ses->Suid, index, srch_inf->entries_in_buffer);
3885 return rc; 3938 return rc;
3886 3939
3887qdir_exit: 3940qdir_exit:
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 538e2299805f..0bd4d4802701 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -288,12 +288,12 @@ struct smb2_encryption_neg_context {
288 __le16 Ciphers[1]; /* Ciphers[0] since only one used now */ 288 __le16 Ciphers[1]; /* Ciphers[0] since only one used now */
289} __packed; 289} __packed;
290 290
291#define POSIX_CTXT_DATA_LEN 8 291#define POSIX_CTXT_DATA_LEN 16
292struct smb2_posix_neg_context { 292struct smb2_posix_neg_context {
293 __le16 ContextType; /* 0x100 */ 293 __le16 ContextType; /* 0x100 */
294 __le16 DataLength; 294 __le16 DataLength;
295 __le32 Reserved; 295 __le32 Reserved;
296 __le64 Reserved1; /* In case needed for future (eg version or caps) */ 296 __u8 Name[16]; /* POSIX ctxt GUID 93AD25509CB411E7B42383DE968BCD7C */
297} __packed; 297} __packed;
298 298
299struct smb2_negotiate_rsp { 299struct smb2_negotiate_rsp {
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 7b351c65ee46..d1181572758b 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -576,6 +576,7 @@ smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
576 struct TCP_Server_Info *server) 576 struct TCP_Server_Info *server)
577{ 577{
578 struct mid_q_entry *temp; 578 struct mid_q_entry *temp;
579 unsigned int credits = le16_to_cpu(shdr->CreditCharge);
579 580
580 if (server == NULL) { 581 if (server == NULL) {
581 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n"); 582 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
@@ -586,6 +587,7 @@ smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
586 memset(temp, 0, sizeof(struct mid_q_entry)); 587 memset(temp, 0, sizeof(struct mid_q_entry));
587 kref_init(&temp->refcount); 588 kref_init(&temp->refcount);
588 temp->mid = le64_to_cpu(shdr->MessageId); 589 temp->mid = le64_to_cpu(shdr->MessageId);
590 temp->credits = credits > 0 ? credits : 1;
589 temp->pid = current->pid; 591 temp->pid = current->pid;
590 temp->command = shdr->Command; /* Always LE */ 592 temp->command = shdr->Command; /* Always LE */
591 temp->when_alloc = jiffies; 593 temp->when_alloc = jiffies;
@@ -600,6 +602,8 @@ smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
600 602
601 atomic_inc(&midCount); 603 atomic_inc(&midCount);
602 temp->mid_state = MID_REQUEST_ALLOCATED; 604 temp->mid_state = MID_REQUEST_ALLOCATED;
605 trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
606 le16_to_cpu(shdr->Command), temp->mid);
603 return temp; 607 return temp;
604} 608}
605 609
@@ -615,6 +619,10 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
615 return -EAGAIN; 619 return -EAGAIN;
616 } 620 }
617 621
622 if (ses->server->tcpStatus == CifsNeedNegotiate &&
623 shdr->Command != SMB2_NEGOTIATE)
624 return -EAGAIN;
625
618 if (ses->status == CifsNew) { 626 if (ses->status == CifsNew) {
619 if ((shdr->Command != SMB2_SESSION_SETUP) && 627 if ((shdr->Command != SMB2_SESSION_SETUP) &&
620 (shdr->Command != SMB2_NEGOTIATE)) 628 (shdr->Command != SMB2_NEGOTIATE))
@@ -634,6 +642,7 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
634 spin_lock(&GlobalMid_Lock); 642 spin_lock(&GlobalMid_Lock);
635 list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q); 643 list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
636 spin_unlock(&GlobalMid_Lock); 644 spin_unlock(&GlobalMid_Lock);
645
637 return 0; 646 return 0;
638} 647}
639 648
@@ -674,13 +683,18 @@ smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
674 smb2_seq_num_into_buf(ses->server, shdr); 683 smb2_seq_num_into_buf(ses->server, shdr);
675 684
676 rc = smb2_get_mid_entry(ses, shdr, &mid); 685 rc = smb2_get_mid_entry(ses, shdr, &mid);
677 if (rc) 686 if (rc) {
687 revert_current_mid_from_hdr(ses->server, shdr);
678 return ERR_PTR(rc); 688 return ERR_PTR(rc);
689 }
690
679 rc = smb2_sign_rqst(rqst, ses->server); 691 rc = smb2_sign_rqst(rqst, ses->server);
680 if (rc) { 692 if (rc) {
693 revert_current_mid_from_hdr(ses->server, shdr);
681 cifs_delete_mid(mid); 694 cifs_delete_mid(mid);
682 return ERR_PTR(rc); 695 return ERR_PTR(rc);
683 } 696 }
697
684 return mid; 698 return mid;
685} 699}
686 700
@@ -692,14 +706,21 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
692 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base; 706 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
693 struct mid_q_entry *mid; 707 struct mid_q_entry *mid;
694 708
709 if (server->tcpStatus == CifsNeedNegotiate &&
710 shdr->Command != SMB2_NEGOTIATE)
711 return ERR_PTR(-EAGAIN);
712
695 smb2_seq_num_into_buf(server, shdr); 713 smb2_seq_num_into_buf(server, shdr);
696 714
697 mid = smb2_mid_entry_alloc(shdr, server); 715 mid = smb2_mid_entry_alloc(shdr, server);
698 if (mid == NULL) 716 if (mid == NULL) {
717 revert_current_mid_from_hdr(server, shdr);
699 return ERR_PTR(-ENOMEM); 718 return ERR_PTR(-ENOMEM);
719 }
700 720
701 rc = smb2_sign_rqst(rqst, server); 721 rc = smb2_sign_rqst(rqst, server);
702 if (rc) { 722 if (rc) {
723 revert_current_mid_from_hdr(server, shdr);
703 DeleteMidQEntry(mid); 724 DeleteMidQEntry(mid);
704 return ERR_PTR(rc); 725 return ERR_PTR(rc);
705 } 726 }
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index a568dac7b3a1..b943b74cd246 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -1550,7 +1550,7 @@ static int allocate_caches_and_workqueue(struct smbd_connection *info)
1550 char name[MAX_NAME_LEN]; 1550 char name[MAX_NAME_LEN];
1551 int rc; 1551 int rc;
1552 1552
1553 snprintf(name, MAX_NAME_LEN, "smbd_request_%p", info); 1553 scnprintf(name, MAX_NAME_LEN, "smbd_request_%p", info);
1554 info->request_cache = 1554 info->request_cache =
1555 kmem_cache_create( 1555 kmem_cache_create(
1556 name, 1556 name,
@@ -1566,7 +1566,7 @@ static int allocate_caches_and_workqueue(struct smbd_connection *info)
1566 if (!info->request_mempool) 1566 if (!info->request_mempool)
1567 goto out1; 1567 goto out1;
1568 1568
1569 snprintf(name, MAX_NAME_LEN, "smbd_response_%p", info); 1569 scnprintf(name, MAX_NAME_LEN, "smbd_response_%p", info);
1570 info->response_cache = 1570 info->response_cache =
1571 kmem_cache_create( 1571 kmem_cache_create(
1572 name, 1572 name,
@@ -1582,7 +1582,7 @@ static int allocate_caches_and_workqueue(struct smbd_connection *info)
1582 if (!info->response_mempool) 1582 if (!info->response_mempool)
1583 goto out3; 1583 goto out3;
1584 1584
1585 snprintf(name, MAX_NAME_LEN, "smbd_%p", info); 1585 scnprintf(name, MAX_NAME_LEN, "smbd_%p", info);
1586 info->workqueue = create_workqueue(name); 1586 info->workqueue = create_workqueue(name);
1587 if (!info->workqueue) 1587 if (!info->workqueue)
1588 goto out4; 1588 goto out4;
diff --git a/fs/cifs/trace.h b/fs/cifs/trace.h
index 59be48206932..d8b049afa606 100644
--- a/fs/cifs/trace.h
+++ b/fs/cifs/trace.h
@@ -58,6 +58,7 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
58 58
59DEFINE_SMB3_RW_ERR_EVENT(write_err); 59DEFINE_SMB3_RW_ERR_EVENT(write_err);
60DEFINE_SMB3_RW_ERR_EVENT(read_err); 60DEFINE_SMB3_RW_ERR_EVENT(read_err);
61DEFINE_SMB3_RW_ERR_EVENT(query_dir_err);
61 62
62 63
63/* For logging successful read or write */ 64/* For logging successful read or write */
@@ -100,8 +101,12 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
100 __u32 len), \ 101 __u32 len), \
101 TP_ARGS(xid, fid, tid, sesid, offset, len)) 102 TP_ARGS(xid, fid, tid, sesid, offset, len))
102 103
104DEFINE_SMB3_RW_DONE_EVENT(write_enter);
105DEFINE_SMB3_RW_DONE_EVENT(read_enter);
106DEFINE_SMB3_RW_DONE_EVENT(query_dir_enter);
103DEFINE_SMB3_RW_DONE_EVENT(write_done); 107DEFINE_SMB3_RW_DONE_EVENT(write_done);
104DEFINE_SMB3_RW_DONE_EVENT(read_done); 108DEFINE_SMB3_RW_DONE_EVENT(read_done);
109DEFINE_SMB3_RW_DONE_EVENT(query_dir_done);
105 110
106/* 111/*
107 * For handle based calls other than read and write, and get/set info 112 * For handle based calls other than read and write, and get/set info
@@ -148,6 +153,48 @@ DEFINE_SMB3_FD_ERR_EVENT(close_err);
148/* 153/*
149 * For handle based query/set info calls 154 * For handle based query/set info calls
150 */ 155 */
156DECLARE_EVENT_CLASS(smb3_inf_enter_class,
157 TP_PROTO(unsigned int xid,
158 __u64 fid,
159 __u32 tid,
160 __u64 sesid,
161 __u8 infclass,
162 __u32 type),
163 TP_ARGS(xid, fid, tid, sesid, infclass, type),
164 TP_STRUCT__entry(
165 __field(unsigned int, xid)
166 __field(__u64, fid)
167 __field(__u32, tid)
168 __field(__u64, sesid)
169 __field(__u8, infclass)
170 __field(__u32, type)
171 ),
172 TP_fast_assign(
173 __entry->xid = xid;
174 __entry->fid = fid;
175 __entry->tid = tid;
176 __entry->sesid = sesid;
177 __entry->infclass = infclass;
178 __entry->type = type;
179 ),
180 TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx class=%u type=0x%x",
181 __entry->xid, __entry->sesid, __entry->tid, __entry->fid,
182 __entry->infclass, __entry->type)
183)
184
185#define DEFINE_SMB3_INF_ENTER_EVENT(name) \
186DEFINE_EVENT(smb3_inf_enter_class, smb3_##name, \
187 TP_PROTO(unsigned int xid, \
188 __u64 fid, \
189 __u32 tid, \
190 __u64 sesid, \
191 __u8 infclass, \
192 __u32 type), \
193 TP_ARGS(xid, fid, tid, sesid, infclass, type))
194
195DEFINE_SMB3_INF_ENTER_EVENT(query_info_enter);
196DEFINE_SMB3_INF_ENTER_EVENT(query_info_done);
197
151DECLARE_EVENT_CLASS(smb3_inf_err_class, 198DECLARE_EVENT_CLASS(smb3_inf_err_class,
152 TP_PROTO(unsigned int xid, 199 TP_PROTO(unsigned int xid,
153 __u64 fid, 200 __u64 fid,
@@ -270,6 +317,7 @@ DEFINE_EVENT(smb3_cmd_done_class, smb3_##name, \
270 __u64 mid), \ 317 __u64 mid), \
271 TP_ARGS(tid, sesid, cmd, mid)) 318 TP_ARGS(tid, sesid, cmd, mid))
272 319
320DEFINE_SMB3_CMD_DONE_EVENT(cmd_enter);
273DEFINE_SMB3_CMD_DONE_EVENT(cmd_done); 321DEFINE_SMB3_CMD_DONE_EVENT(cmd_done);
274DEFINE_SMB3_CMD_DONE_EVENT(ses_expired); 322DEFINE_SMB3_CMD_DONE_EVENT(ses_expired);
275 323
@@ -406,8 +454,47 @@ DEFINE_SMB3_TCON_EVENT(tcon);
406 454
407 455
408/* 456/*
409 * For smb2/smb3 open call 457 * For smb2/smb3 open (including create and mkdir) calls
410 */ 458 */
459
460DECLARE_EVENT_CLASS(smb3_open_enter_class,
461 TP_PROTO(unsigned int xid,
462 __u32 tid,
463 __u64 sesid,
464 int create_options,
465 int desired_access),
466 TP_ARGS(xid, tid, sesid, create_options, desired_access),
467 TP_STRUCT__entry(
468 __field(unsigned int, xid)
469 __field(__u32, tid)
470 __field(__u64, sesid)
471 __field(int, create_options)
472 __field(int, desired_access)
473 ),
474 TP_fast_assign(
475 __entry->xid = xid;
476 __entry->tid = tid;
477 __entry->sesid = sesid;
478 __entry->create_options = create_options;
479 __entry->desired_access = desired_access;
480 ),
481 TP_printk("xid=%u sid=0x%llx tid=0x%x cr_opts=0x%x des_access=0x%x",
482 __entry->xid, __entry->sesid, __entry->tid,
483 __entry->create_options, __entry->desired_access)
484)
485
486#define DEFINE_SMB3_OPEN_ENTER_EVENT(name) \
487DEFINE_EVENT(smb3_open_enter_class, smb3_##name, \
488 TP_PROTO(unsigned int xid, \
489 __u32 tid, \
490 __u64 sesid, \
491 int create_options, \
492 int desired_access), \
493 TP_ARGS(xid, tid, sesid, create_options, desired_access))
494
495DEFINE_SMB3_OPEN_ENTER_EVENT(open_enter);
496DEFINE_SMB3_OPEN_ENTER_EVENT(posix_mkdir_enter);
497
411DECLARE_EVENT_CLASS(smb3_open_err_class, 498DECLARE_EVENT_CLASS(smb3_open_err_class,
412 TP_PROTO(unsigned int xid, 499 TP_PROTO(unsigned int xid,
413 __u32 tid, 500 __u32 tid,
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 53532bd3f50d..7ce8a585abd6 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -33,6 +33,7 @@
33#include <linux/uaccess.h> 33#include <linux/uaccess.h>
34#include <asm/processor.h> 34#include <asm/processor.h>
35#include <linux/mempool.h> 35#include <linux/mempool.h>
36#include <linux/signal.h>
36#include "cifspdu.h" 37#include "cifspdu.h"
37#include "cifsglob.h" 38#include "cifsglob.h"
38#include "cifsproto.h" 39#include "cifsproto.h"
@@ -291,6 +292,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
291 int n_vec; 292 int n_vec;
292 unsigned int send_length = 0; 293 unsigned int send_length = 0;
293 unsigned int i, j; 294 unsigned int i, j;
295 sigset_t mask, oldmask;
294 size_t total_len = 0, sent, size; 296 size_t total_len = 0, sent, size;
295 struct socket *ssocket = server->ssocket; 297 struct socket *ssocket = server->ssocket;
296 struct msghdr smb_msg; 298 struct msghdr smb_msg;
@@ -301,8 +303,14 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
301 rc = smbd_send(server, rqst); 303 rc = smbd_send(server, rqst);
302 goto smbd_done; 304 goto smbd_done;
303 } 305 }
306
304 if (ssocket == NULL) 307 if (ssocket == NULL)
305 return -ENOTSOCK; 308 return -EAGAIN;
309
310 if (signal_pending(current)) {
311 cifs_dbg(FYI, "signal is pending before sending any data\n");
312 return -EINTR;
313 }
306 314
307 /* cork the socket */ 315 /* cork the socket */
308 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK, 316 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
@@ -312,6 +320,16 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
312 send_length += smb_rqst_len(server, &rqst[j]); 320 send_length += smb_rqst_len(server, &rqst[j]);
313 rfc1002_marker = cpu_to_be32(send_length); 321 rfc1002_marker = cpu_to_be32(send_length);
314 322
323 /*
324 * We should not allow signals to interrupt the network send because
325 * any partial send will cause session reconnects thus increasing
326 * latency of system calls and overload a server with unnecessary
327 * requests.
328 */
329
330 sigfillset(&mask);
331 sigprocmask(SIG_BLOCK, &mask, &oldmask);
332
315 /* Generate a rfc1002 marker for SMB2+ */ 333 /* Generate a rfc1002 marker for SMB2+ */
316 if (server->vals->header_preamble_size == 0) { 334 if (server->vals->header_preamble_size == 0) {
317 struct kvec hiov = { 335 struct kvec hiov = {
@@ -321,7 +339,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
321 iov_iter_kvec(&smb_msg.msg_iter, WRITE, &hiov, 1, 4); 339 iov_iter_kvec(&smb_msg.msg_iter, WRITE, &hiov, 1, 4);
322 rc = smb_send_kvec(server, &smb_msg, &sent); 340 rc = smb_send_kvec(server, &smb_msg, &sent);
323 if (rc < 0) 341 if (rc < 0)
324 goto uncork; 342 goto unmask;
325 343
326 total_len += sent; 344 total_len += sent;
327 send_length += 4; 345 send_length += 4;
@@ -343,7 +361,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
343 361
344 rc = smb_send_kvec(server, &smb_msg, &sent); 362 rc = smb_send_kvec(server, &smb_msg, &sent);
345 if (rc < 0) 363 if (rc < 0)
346 goto uncork; 364 goto unmask;
347 365
348 total_len += sent; 366 total_len += sent;
349 367
@@ -365,7 +383,25 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
365 } 383 }
366 } 384 }
367 385
368uncork: 386unmask:
387 sigprocmask(SIG_SETMASK, &oldmask, NULL);
388
389 /*
390 * If signal is pending but we have already sent the whole packet to
391 * the server we need to return success status to allow a corresponding
392 * mid entry to be kept in the pending requests queue thus allowing
393 * to handle responses from the server by the client.
394 *
395 * If only part of the packet has been sent there is no need to hide
396 * interrupt because the session will be reconnected anyway, so there
397 * won't be any response from the server to handle.
398 */
399
400 if (signal_pending(current) && (total_len != send_length)) {
401 cifs_dbg(FYI, "signal is pending after attempt to send\n");
402 rc = -EINTR;
403 }
404
369 /* uncork it */ 405 /* uncork it */
370 val = 0; 406 val = 0;
371 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK, 407 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
@@ -451,15 +487,18 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
451 487
452static int 488static int
453wait_for_free_credits(struct TCP_Server_Info *server, const int timeout, 489wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
454 int *credits) 490 int *credits, unsigned int *instance)
455{ 491{
456 int rc; 492 int rc;
457 493
494 *instance = 0;
495
458 spin_lock(&server->req_lock); 496 spin_lock(&server->req_lock);
459 if (timeout == CIFS_ASYNC_OP) { 497 if (timeout == CIFS_ASYNC_OP) {
460 /* oplock breaks must not be held up */ 498 /* oplock breaks must not be held up */
461 server->in_flight++; 499 server->in_flight++;
462 *credits -= 1; 500 *credits -= 1;
501 *instance = server->reconnect_instance;
463 spin_unlock(&server->req_lock); 502 spin_unlock(&server->req_lock);
464 return 0; 503 return 0;
465 } 504 }
@@ -489,6 +528,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
489 if (timeout != CIFS_BLOCKING_OP) { 528 if (timeout != CIFS_BLOCKING_OP) {
490 *credits -= 1; 529 *credits -= 1;
491 server->in_flight++; 530 server->in_flight++;
531 *instance = server->reconnect_instance;
492 } 532 }
493 spin_unlock(&server->req_lock); 533 spin_unlock(&server->req_lock);
494 break; 534 break;
@@ -499,7 +539,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
499 539
500static int 540static int
501wait_for_free_request(struct TCP_Server_Info *server, const int timeout, 541wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
502 const int optype) 542 const int optype, unsigned int *instance)
503{ 543{
504 int *val; 544 int *val;
505 545
@@ -507,15 +547,16 @@ wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
507 /* Since an echo is already inflight, no need to wait to send another */ 547 /* Since an echo is already inflight, no need to wait to send another */
508 if (*val <= 0 && optype == CIFS_ECHO_OP) 548 if (*val <= 0 && optype == CIFS_ECHO_OP)
509 return -EAGAIN; 549 return -EAGAIN;
510 return wait_for_free_credits(server, timeout, val); 550 return wait_for_free_credits(server, timeout, val, instance);
511} 551}
512 552
513int 553int
514cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, 554cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
515 unsigned int *num, unsigned int *credits) 555 unsigned int *num, struct cifs_credits *credits)
516{ 556{
517 *num = size; 557 *num = size;
518 *credits = 0; 558 credits->value = 0;
559 credits->instance = server->reconnect_instance;
519 return 0; 560 return 0;
520} 561}
521 562
@@ -602,27 +643,43 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
602int 643int
603cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, 644cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
604 mid_receive_t *receive, mid_callback_t *callback, 645 mid_receive_t *receive, mid_callback_t *callback,
605 mid_handle_t *handle, void *cbdata, const int flags) 646 mid_handle_t *handle, void *cbdata, const int flags,
647 const struct cifs_credits *exist_credits)
606{ 648{
607 int rc, timeout, optype; 649 int rc, timeout, optype;
608 struct mid_q_entry *mid; 650 struct mid_q_entry *mid;
609 unsigned int credits = 0; 651 struct cifs_credits credits = { .value = 0, .instance = 0 };
652 unsigned int instance;
610 653
611 timeout = flags & CIFS_TIMEOUT_MASK; 654 timeout = flags & CIFS_TIMEOUT_MASK;
612 optype = flags & CIFS_OP_MASK; 655 optype = flags & CIFS_OP_MASK;
613 656
614 if ((flags & CIFS_HAS_CREDITS) == 0) { 657 if ((flags & CIFS_HAS_CREDITS) == 0) {
615 rc = wait_for_free_request(server, timeout, optype); 658 rc = wait_for_free_request(server, timeout, optype, &instance);
616 if (rc) 659 if (rc)
617 return rc; 660 return rc;
618 credits = 1; 661 credits.value = 1;
619 } 662 credits.instance = instance;
663 } else
664 instance = exist_credits->instance;
620 665
621 mutex_lock(&server->srv_mutex); 666 mutex_lock(&server->srv_mutex);
667
668 /*
669 * We can't use credits obtained from the previous session to send this
670 * request. Check if there were reconnects after we obtained credits and
671 * return -EAGAIN in such cases to let callers handle it.
672 */
673 if (instance != server->reconnect_instance) {
674 mutex_unlock(&server->srv_mutex);
675 add_credits_and_wake_if(server, &credits, optype);
676 return -EAGAIN;
677 }
678
622 mid = server->ops->setup_async_request(server, rqst); 679 mid = server->ops->setup_async_request(server, rqst);
623 if (IS_ERR(mid)) { 680 if (IS_ERR(mid)) {
624 mutex_unlock(&server->srv_mutex); 681 mutex_unlock(&server->srv_mutex);
625 add_credits_and_wake_if(server, credits, optype); 682 add_credits_and_wake_if(server, &credits, optype);
626 return PTR_ERR(mid); 683 return PTR_ERR(mid);
627 } 684 }
628 685
@@ -647,6 +704,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
647 cifs_in_send_dec(server); 704 cifs_in_send_dec(server);
648 705
649 if (rc < 0) { 706 if (rc < 0) {
707 revert_current_mid(server, mid->credits);
650 server->sequence_number -= 2; 708 server->sequence_number -= 2;
651 cifs_delete_mid(mid); 709 cifs_delete_mid(mid);
652 } 710 }
@@ -656,7 +714,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
656 if (rc == 0) 714 if (rc == 0)
657 return 0; 715 return 0;
658 716
659 add_credits_and_wake_if(server, credits, optype); 717 add_credits_and_wake_if(server, &credits, optype);
660 return rc; 718 return rc;
661} 719}
662 720
@@ -786,8 +844,12 @@ static void
786cifs_compound_callback(struct mid_q_entry *mid) 844cifs_compound_callback(struct mid_q_entry *mid)
787{ 845{
788 struct TCP_Server_Info *server = mid->server; 846 struct TCP_Server_Info *server = mid->server;
847 struct cifs_credits credits;
848
849 credits.value = server->ops->get_credits(mid);
850 credits.instance = server->reconnect_instance;
789 851
790 add_credits(server, server->ops->get_credits(mid), mid->optype); 852 add_credits(server, &credits, mid->optype);
791} 853}
792 854
793static void 855static void
@@ -813,7 +875,11 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
813 int timeout, optype; 875 int timeout, optype;
814 struct mid_q_entry *midQ[MAX_COMPOUND]; 876 struct mid_q_entry *midQ[MAX_COMPOUND];
815 bool cancelled_mid[MAX_COMPOUND] = {false}; 877 bool cancelled_mid[MAX_COMPOUND] = {false};
816 unsigned int credits[MAX_COMPOUND] = {0}; 878 struct cifs_credits credits[MAX_COMPOUND] = {
879 { .value = 0, .instance = 0 }
880 };
881 unsigned int instance;
882 unsigned int first_instance = 0;
817 char *buf; 883 char *buf;
818 884
819 timeout = flags & CIFS_TIMEOUT_MASK; 885 timeout = flags & CIFS_TIMEOUT_MASK;
@@ -830,16 +896,64 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
830 if (ses->server->tcpStatus == CifsExiting) 896 if (ses->server->tcpStatus == CifsExiting)
831 return -ENOENT; 897 return -ENOENT;
832 898
899 spin_lock(&ses->server->req_lock);
900 if (ses->server->credits < num_rqst) {
901 /*
902 * Return immediately if not too many requests in flight since
903 * we will likely be stuck on waiting for credits.
904 */
905 if (ses->server->in_flight < num_rqst - ses->server->credits) {
906 spin_unlock(&ses->server->req_lock);
907 return -ENOTSUPP;
908 }
909 } else {
910 /* enough credits to send the whole compounded request */
911 ses->server->credits -= num_rqst;
912 ses->server->in_flight += num_rqst;
913 first_instance = ses->server->reconnect_instance;
914 }
915 spin_unlock(&ses->server->req_lock);
916
917 if (first_instance) {
918 cifs_dbg(FYI, "Acquired %d credits at once\n", num_rqst);
919 for (i = 0; i < num_rqst; i++) {
920 credits[i].value = 1;
921 credits[i].instance = first_instance;
922 }
923 goto setup_rqsts;
924 }
925
833 /* 926 /*
927 * There are not enough credits to send the whole compound request but
928 * there are requests in flight that may bring credits from the server.
929 * This approach still leaves the possibility to be stuck waiting for
930 * credits if the server doesn't grant credits to the outstanding
931 * requests. This should be fixed by returning immediately and letting
932 * a caller fallback to sequential commands instead of compounding.
834 * Ensure we obtain 1 credit per request in the compound chain. 933 * Ensure we obtain 1 credit per request in the compound chain.
835 * It can be optimized further by waiting for all the credits
836 * at once but this can wait long enough if we don't have enough
837 * credits due to some heavy operations in progress or the server
838 * not granting us much, so a fallback to the current approach is
839 * needed anyway.
840 */ 934 */
841 for (i = 0; i < num_rqst; i++) { 935 for (i = 0; i < num_rqst; i++) {
842 rc = wait_for_free_request(ses->server, timeout, optype); 936 rc = wait_for_free_request(ses->server, timeout, optype,
937 &instance);
938
939 if (rc == 0) {
940 credits[i].value = 1;
941 credits[i].instance = instance;
942 /*
943 * All parts of the compound chain must get credits from
944 * the same session, otherwise we may end up using more
945 * credits than the server granted. If there were
946 * reconnects in between, return -EAGAIN and let callers
947 * handle it.
948 */
949 if (i == 0)
950 first_instance = instance;
951 else if (first_instance != instance) {
952 i++;
953 rc = -EAGAIN;
954 }
955 }
956
843 if (rc) { 957 if (rc) {
844 /* 958 /*
845 * We haven't sent an SMB packet to the server yet but 959 * We haven't sent an SMB packet to the server yet but
@@ -851,12 +965,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
851 * requests correctly. 965 * requests correctly.
852 */ 966 */
853 for (j = 0; j < i; j++) 967 for (j = 0; j < i; j++)
854 add_credits(ses->server, 1, optype); 968 add_credits(ses->server, &credits[j], optype);
855 return rc; 969 return rc;
856 } 970 }
857 credits[i] = 1;
858 } 971 }
859 972
973setup_rqsts:
860 /* 974 /*
861 * Make sure that we sign in the same order that we send on this socket 975 * Make sure that we sign in the same order that we send on this socket
862 * and avoid races inside tcp sendmsg code that could cause corruption 976 * and avoid races inside tcp sendmsg code that could cause corruption
@@ -865,16 +979,33 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
865 979
866 mutex_lock(&ses->server->srv_mutex); 980 mutex_lock(&ses->server->srv_mutex);
867 981
982 /*
983 * All the parts of the compound chain belong obtained credits from the
984 * same session (see the appropriate checks above). In the same time
985 * there might be reconnects after those checks but before we acquired
986 * the srv_mutex. We can not use credits obtained from the previous
987 * session to send this request. Check if there were reconnects after
988 * we obtained credits and return -EAGAIN in such cases to let callers
989 * handle it.
990 */
991 if (first_instance != ses->server->reconnect_instance) {
992 mutex_unlock(&ses->server->srv_mutex);
993 for (j = 0; j < num_rqst; j++)
994 add_credits(ses->server, &credits[j], optype);
995 return -EAGAIN;
996 }
997
868 for (i = 0; i < num_rqst; i++) { 998 for (i = 0; i < num_rqst; i++) {
869 midQ[i] = ses->server->ops->setup_request(ses, &rqst[i]); 999 midQ[i] = ses->server->ops->setup_request(ses, &rqst[i]);
870 if (IS_ERR(midQ[i])) { 1000 if (IS_ERR(midQ[i])) {
1001 revert_current_mid(ses->server, i);
871 for (j = 0; j < i; j++) 1002 for (j = 0; j < i; j++)
872 cifs_delete_mid(midQ[j]); 1003 cifs_delete_mid(midQ[j]);
873 mutex_unlock(&ses->server->srv_mutex); 1004 mutex_unlock(&ses->server->srv_mutex);
874 1005
875 /* Update # of requests on wire to server */ 1006 /* Update # of requests on wire to server */
876 for (j = 0; j < num_rqst; j++) 1007 for (j = 0; j < num_rqst; j++)
877 add_credits(ses->server, credits[j], optype); 1008 add_credits(ses->server, &credits[j], optype);
878 return PTR_ERR(midQ[i]); 1009 return PTR_ERR(midQ[i]);
879 } 1010 }
880 1011
@@ -897,15 +1028,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
897 for (i = 0; i < num_rqst; i++) 1028 for (i = 0; i < num_rqst; i++)
898 cifs_save_when_sent(midQ[i]); 1029 cifs_save_when_sent(midQ[i]);
899 1030
900 if (rc < 0) 1031 if (rc < 0) {
1032 revert_current_mid(ses->server, num_rqst);
901 ses->server->sequence_number -= 2; 1033 ses->server->sequence_number -= 2;
1034 }
902 1035
903 mutex_unlock(&ses->server->srv_mutex); 1036 mutex_unlock(&ses->server->srv_mutex);
904 1037
905 if (rc < 0) { 1038 if (rc < 0) {
906 /* Sending failed for some reason - return credits back */ 1039 /* Sending failed for some reason - return credits back */
907 for (i = 0; i < num_rqst; i++) 1040 for (i = 0; i < num_rqst; i++)
908 add_credits(ses->server, credits[i], optype); 1041 add_credits(ses->server, &credits[i], optype);
909 goto out; 1042 goto out;
910 } 1043 }
911 1044
@@ -942,7 +1075,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
942 midQ[i]->mid_flags |= MID_WAIT_CANCELLED; 1075 midQ[i]->mid_flags |= MID_WAIT_CANCELLED;
943 midQ[i]->callback = cifs_cancelled_callback; 1076 midQ[i]->callback = cifs_cancelled_callback;
944 cancelled_mid[i] = true; 1077 cancelled_mid[i] = true;
945 credits[i] = 0; 1078 credits[i].value = 0;
946 } 1079 }
947 spin_unlock(&GlobalMid_Lock); 1080 spin_unlock(&GlobalMid_Lock);
948 } 1081 }
@@ -1068,6 +1201,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
1068 unsigned int len = be32_to_cpu(in_buf->smb_buf_length); 1201 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
1069 struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 1202 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
1070 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 1203 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
1204 struct cifs_credits credits = { .value = 1, .instance = 0 };
1071 1205
1072 if (ses == NULL) { 1206 if (ses == NULL) {
1073 cifs_dbg(VFS, "Null smb session\n"); 1207 cifs_dbg(VFS, "Null smb session\n");
@@ -1091,7 +1225,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
1091 return -EIO; 1225 return -EIO;
1092 } 1226 }
1093 1227
1094 rc = wait_for_free_request(ses->server, timeout, 0); 1228 rc = wait_for_free_request(ses->server, timeout, 0, &credits.instance);
1095 if (rc) 1229 if (rc)
1096 return rc; 1230 return rc;
1097 1231
@@ -1105,7 +1239,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
1105 if (rc) { 1239 if (rc) {
1106 mutex_unlock(&ses->server->srv_mutex); 1240 mutex_unlock(&ses->server->srv_mutex);
1107 /* Update # of requests on wire to server */ 1241 /* Update # of requests on wire to server */
1108 add_credits(ses->server, 1, 0); 1242 add_credits(ses->server, &credits, 0);
1109 return rc; 1243 return rc;
1110 } 1244 }
1111 1245
@@ -1141,7 +1275,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
1141 /* no longer considered to be "in-flight" */ 1275 /* no longer considered to be "in-flight" */
1142 midQ->callback = DeleteMidQEntry; 1276 midQ->callback = DeleteMidQEntry;
1143 spin_unlock(&GlobalMid_Lock); 1277 spin_unlock(&GlobalMid_Lock);
1144 add_credits(ses->server, 1, 0); 1278 add_credits(ses->server, &credits, 0);
1145 return rc; 1279 return rc;
1146 } 1280 }
1147 spin_unlock(&GlobalMid_Lock); 1281 spin_unlock(&GlobalMid_Lock);
@@ -1149,7 +1283,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
1149 1283
1150 rc = cifs_sync_mid_result(midQ, ses->server); 1284 rc = cifs_sync_mid_result(midQ, ses->server);
1151 if (rc != 0) { 1285 if (rc != 0) {
1152 add_credits(ses->server, 1, 0); 1286 add_credits(ses->server, &credits, 0);
1153 return rc; 1287 return rc;
1154 } 1288 }
1155 1289
@@ -1165,7 +1299,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
1165 rc = cifs_check_receive(midQ, ses->server, 0); 1299 rc = cifs_check_receive(midQ, ses->server, 0);
1166out: 1300out:
1167 cifs_delete_mid(midQ); 1301 cifs_delete_mid(midQ);
1168 add_credits(ses->server, 1, 0); 1302 add_credits(ses->server, &credits, 0);
1169 1303
1170 return rc; 1304 return rc;
1171} 1305}
@@ -1207,6 +1341,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
1207 unsigned int len = be32_to_cpu(in_buf->smb_buf_length); 1341 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
1208 struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 1342 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
1209 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 1343 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
1344 unsigned int instance;
1210 1345
1211 if (tcon == NULL || tcon->ses == NULL) { 1346 if (tcon == NULL || tcon->ses == NULL) {
1212 cifs_dbg(VFS, "Null smb session\n"); 1347 cifs_dbg(VFS, "Null smb session\n");
@@ -1232,7 +1367,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
1232 return -EIO; 1367 return -EIO;
1233 } 1368 }
1234 1369
1235 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0); 1370 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0,
1371 &instance);
1236 if (rc) 1372 if (rc)
1237 return rc; 1373 return rc;
1238 1374