aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/README27
-rw-r--r--fs/cifs/TODO2
-rw-r--r--fs/cifs/cifs_spnego.c20
-rw-r--r--fs/cifs/cifs_spnego.h1
-rw-r--r--fs/cifs/cifsacl.c13
-rw-r--r--fs/cifs/cifsfs.c7
-rw-r--r--fs/cifs/cifsglob.h13
-rw-r--r--fs/cifs/cifsproto.h17
-rw-r--r--fs/cifs/cifssmb.c97
-rw-r--r--fs/cifs/connect.c141
-rw-r--r--fs/cifs/file.c44
-rw-r--r--fs/cifs/inode.c26
-rw-r--r--fs/cifs/sess.c93
-rw-r--r--fs/cifs/transport.c91
-rw-r--r--fs/proc/array.c4
16 files changed, 370 insertions, 229 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 64dd22239b21..a609599287aa 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,6 +1,9 @@
1Version 1.52 1Version 1.52
2------------ 2------------
3Fix oops on second mount to server when null auth is used. 3Fix oops on second mount to server when null auth is used.
4Enable experimental Kerberos support. Return writebehind errors on flush
5and sync so that events like out of disk space get reported properly on
6cached files.
4 7
5Version 1.51 8Version 1.51
6------------ 9------------
diff --git a/fs/cifs/README b/fs/cifs/README
index b806b11b5560..bf11329ac784 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -225,12 +225,9 @@ If no password is provided, mount.cifs will prompt for password entry
225 225
226Restrictions 226Restrictions
227============ 227============
228Servers must support the NTLM SMB dialect (which is the most recent, supported
229by Samba and Windows NT version 4, 2000 and XP and many other SMB/CIFS servers)
230Servers must support either "pure-TCP" (port 445 TCP/IP CIFS connections) or RFC 228Servers must support either "pure-TCP" (port 445 TCP/IP CIFS connections) or RFC
2311001/1002 support for "Netbios-Over-TCP/IP." Neither of these is likely to be a 2291001/1002 support for "Netbios-Over-TCP/IP." This is not likely to be a
232problem as most servers support this. IPv6 support is planned for the future, 230problem as most servers support this.
233and is almost complete.
234 231
235Valid filenames differ between Windows and Linux. Windows typically restricts 232Valid filenames differ between Windows and Linux. Windows typically restricts
236filenames which contain certain reserved characters (e.g.the character : 233filenames which contain certain reserved characters (e.g.the character :
@@ -458,6 +455,8 @@ A partial list of the supported mount options follows:
458 byte range locks). 455 byte range locks).
459 remount remount the share (often used to change from ro to rw mounts 456 remount remount the share (often used to change from ro to rw mounts
460 or vice versa) 457 or vice versa)
458 cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for
459 the file. (EXPERIMENTAL)
461 servern Specify the server 's netbios name (RFC1001 name) to use 460 servern Specify the server 's netbios name (RFC1001 name) to use
462 when attempting to setup a session to the server. This is 461 when attempting to setup a session to the server. This is
463 This is needed for mounting to some older servers (such 462 This is needed for mounting to some older servers (such
@@ -584,8 +583,8 @@ Experimental When set to 1 used to enable certain experimental
584 performance enhancement was disabled when 583 performance enhancement was disabled when
585 signing turned on in case buffer was modified 584 signing turned on in case buffer was modified
586 just before it was sent, also this flag will 585 just before it was sent, also this flag will
587 be used to use the new experimental sessionsetup 586 be used to use the new experimental directory change
588 code). 587 notification code).
589 588
590These experimental features and tracing can be enabled by changing flags in 589These experimental features and tracing can be enabled by changing flags in
591/proc/fs/cifs (after the cifs module has been installed or built into the 590/proc/fs/cifs (after the cifs module has been installed or built into the
@@ -608,7 +607,8 @@ the start of smb requests and responses can be enabled via:
608Two other experimental features are under development. To test these 607Two other experimental features are under development. To test these
609requires enabling CONFIG_CIFS_EXPERIMENTAL 608requires enabling CONFIG_CIFS_EXPERIMENTAL
610 609
611 ipv6 enablement 610 cifsacl support needed to retrieve approximated mode bits based on
611 the contents on the CIFS ACL.
612 612
613 DNOTIFY fcntl: needed for support of directory change 613 DNOTIFY fcntl: needed for support of directory change
614 notification and perhaps later for file leases) 614 notification and perhaps later for file leases)
@@ -625,10 +625,7 @@ that they represent all for that share, not just those for which the server
625returned success. 625returned success.
626 626
627Also note that "cat /proc/fs/cifs/DebugData" will display information about 627Also note that "cat /proc/fs/cifs/DebugData" will display information about
628the active sessions and the shares that are mounted. Note: NTLMv2 enablement 628the active sessions and the shares that are mounted.
629will not work since its implementation is not quite complete yet. Do not alter 629Enabling Kerberos (extended security) works when CONFIG_CIFS_EXPERIMENTAL is enabled
630the ExtendedSecurity configuration value unless you are doing specific testing. 630but requires a user space helper (from the Samba project). NTLM and NTLMv2 and
631Enabling extended security works to Windows 2000 Workstations and XP but not to 631LANMAN support do not require this helpr.
632Windows 2000 server or Samba since it does not usually send "raw NTLMSSP"
633(instead it sends NTLMSSP encapsulated in SPNEGO/GSSAPI, which support is not
634complete in the CIFS VFS yet).
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 29d4b2715254..a8852c200728 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -16,7 +16,7 @@ SecurityDescriptors
16c) Better pam/winbind integration (e.g. to handle uid mapping 16c) Better pam/winbind integration (e.g. to handle uid mapping
17better) 17better)
18 18
19d) Kerberos/SPNEGO session setup support - (started) 19d) Verify that Kerberos signing works
20 20
21e) Cleanup now unneeded SessSetup code in 21e) Cleanup now unneeded SessSetup code in
22fs/cifs/connect.c and add back in NTLMSSP code if any servers 22fs/cifs/connect.c and add back in NTLMSSP code if any servers
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index ad54a3a6e434..1529d2b12e9c 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -66,20 +66,26 @@ struct key_type cifs_spnego_key_type = {
66 .describe = user_describe, 66 .describe = user_describe,
67}; 67};
68 68
69#define MAX_VER_STR_LEN 9 /* length of longest version string e.g.
70 strlen(";ver=0xFF") */
71#define MAX_MECH_STR_LEN 13 /* length of longest security mechanism name, eg
72 in future could have strlen(";sec=ntlmsspi") */
73#define MAX_IPV6_ADDR_LEN 42 /* eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */
69/* get a key struct with a SPNEGO security blob, suitable for session setup */ 74/* get a key struct with a SPNEGO security blob, suitable for session setup */
70struct key * 75struct key *
71cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const char *hostname) 76cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
72{ 77{
73 struct TCP_Server_Info *server = sesInfo->server; 78 struct TCP_Server_Info *server = sesInfo->server;
74 char *description, *dp; 79 char *description, *dp;
75 size_t desc_len; 80 size_t desc_len;
76 struct key *spnego_key; 81 struct key *spnego_key;
82 const char *hostname = server->hostname;
77 83
78 84 /* BB: come up with better scheme for determining length */
79 /* version + ;ip{4|6}= + address + ;host=hostname + 85 /* length of fields (with semicolons): ver=0xyz ipv4= ipaddress host=
80 ;sec= + ;uid= + NULL */ 86 hostname sec=mechanism uid=0x uid */
81 desc_len = 4 + 5 + 32 + 1 + 5 + strlen(hostname) + 87 desc_len = MAX_VER_STR_LEN + 5 + MAX_IPV6_ADDR_LEN + 1 + 6 +
82 strlen(";sec=krb5") + 7 + sizeof(uid_t)*2 + 1; 88 strlen(hostname) + MAX_MECH_STR_LEN + 8 + (sizeof(uid_t) * 2);
83 spnego_key = ERR_PTR(-ENOMEM); 89 spnego_key = ERR_PTR(-ENOMEM);
84 description = kzalloc(desc_len, GFP_KERNEL); 90 description = kzalloc(desc_len, GFP_KERNEL);
85 if (description == NULL) 91 if (description == NULL)
@@ -88,7 +94,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const char *hostname)
88 dp = description; 94 dp = description;
89 /* start with version and hostname portion of UNC string */ 95 /* start with version and hostname portion of UNC string */
90 spnego_key = ERR_PTR(-EINVAL); 96 spnego_key = ERR_PTR(-EINVAL);
91 sprintf(dp, "0x%2.2x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION, 97 sprintf(dp, "ver=0x%x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION,
92 hostname); 98 hostname);
93 dp = description + strlen(description); 99 dp = description + strlen(description);
94 100
diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h
index f443f3b35134..05a34b17a1ab 100644
--- a/fs/cifs/cifs_spnego.h
+++ b/fs/cifs/cifs_spnego.h
@@ -41,6 +41,7 @@ struct cifs_spnego_msg {
41 41
42#ifdef __KERNEL__ 42#ifdef __KERNEL__
43extern struct key_type cifs_spnego_key_type; 43extern struct key_type cifs_spnego_key_type;
44extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo);
44#endif /* KERNEL */ 45#endif /* KERNEL */
45 46
46#endif /* _CIFS_SPNEGO_H */ 47#endif /* _CIFS_SPNEGO_H */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index dabbce00712b..f02fdef463a7 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -269,6 +269,13 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
269 269
270 /* BB need to add parm so we can store the SID BB */ 270 /* BB need to add parm so we can store the SID BB */
271 271
272 if (!pdacl) {
273 /* no DACL in the security descriptor, set
274 all the permissions for user/group/other */
275 inode->i_mode |= S_IRWXUGO;
276 return;
277 }
278
272 /* validate that we do not go past end of acl */ 279 /* validate that we do not go past end of acl */
273 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { 280 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
274 cERROR(1, ("ACL too small to parse DACL")); 281 cERROR(1, ("ACL too small to parse DACL"));
@@ -286,12 +293,6 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
286 user/group/other have no permissions */ 293 user/group/other have no permissions */
287 inode->i_mode &= ~(S_IRWXUGO); 294 inode->i_mode &= ~(S_IRWXUGO);
288 295
289 if (!pdacl) {
290 /* no DACL in the security descriptor, set
291 all the permissions for user/group/other */
292 inode->i_mode |= S_IRWXUGO;
293 return;
294 }
295 acl_base = (char *)pdacl; 296 acl_base = (char *)pdacl;
296 acl_size = sizeof(struct cifs_acl); 297 acl_size = sizeof(struct cifs_acl);
297 298
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 416dc9fe8961..093beaa3900d 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -266,6 +266,7 @@ cifs_alloc_inode(struct super_block *sb)
266 cifs_inode->cifsAttrs = 0x20; /* default */ 266 cifs_inode->cifsAttrs = 0x20; /* default */
267 atomic_set(&cifs_inode->inUse, 0); 267 atomic_set(&cifs_inode->inUse, 0);
268 cifs_inode->time = 0; 268 cifs_inode->time = 0;
269 cifs_inode->write_behind_rc = 0;
269 /* Until the file is open and we have gotten oplock 270 /* Until the file is open and we have gotten oplock
270 info back from the server, can not assume caching of 271 info back from the server, can not assume caching of
271 file data or metadata */ 272 file data or metadata */
@@ -852,7 +853,7 @@ static int cifs_oplock_thread(void *dummyarg)
852 struct cifsTconInfo *pTcon; 853 struct cifsTconInfo *pTcon;
853 struct inode *inode; 854 struct inode *inode;
854 __u16 netfid; 855 __u16 netfid;
855 int rc; 856 int rc, waitrc = 0;
856 857
857 set_freezable(); 858 set_freezable();
858 do { 859 do {
@@ -884,9 +885,11 @@ static int cifs_oplock_thread(void *dummyarg)
884 filemap_fdatawrite(inode->i_mapping); 885 filemap_fdatawrite(inode->i_mapping);
885 if (CIFS_I(inode)->clientCanCacheRead 886 if (CIFS_I(inode)->clientCanCacheRead
886 == 0) { 887 == 0) {
887 filemap_fdatawait(inode->i_mapping); 888 waitrc = filemap_fdatawait(inode->i_mapping);
888 invalidate_remote_inode(inode); 889 invalidate_remote_inode(inode);
889 } 890 }
891 if (rc == 0)
892 rc = waitrc;
890 } else 893 } else
891 rc = 0; 894 rc = 0;
892 /* mutex_unlock(&inode->i_mutex);*/ 895 /* mutex_unlock(&inode->i_mutex);*/
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 87f51f23276f..1fde2197ad76 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -110,6 +110,7 @@ struct mac_key {
110 unsigned int len; 110 unsigned int len;
111 union { 111 union {
112 char ntlm[CIFS_SESS_KEY_SIZE + 16]; 112 char ntlm[CIFS_SESS_KEY_SIZE + 16];
113 char krb5[CIFS_SESS_KEY_SIZE + 16]; /* BB: length correct? */
113 struct { 114 struct {
114 char key[16]; 115 char key[16];
115 struct ntlmv2_resp resp; 116 struct ntlmv2_resp resp;
@@ -139,6 +140,7 @@ struct TCP_Server_Info {
139 /* 15 character server name + 0x20 16th byte indicating type = srv */ 140 /* 15 character server name + 0x20 16th byte indicating type = srv */
140 char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; 141 char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
141 char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; 142 char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
143 char *hostname; /* hostname portion of UNC string */
142 struct socket *ssocket; 144 struct socket *ssocket;
143 union { 145 union {
144 struct sockaddr_in sockAddr; 146 struct sockaddr_in sockAddr;
@@ -471,6 +473,17 @@ struct dir_notify_req {
471#define CIFS_LARGE_BUFFER 2 473#define CIFS_LARGE_BUFFER 2
472#define CIFS_IOVEC 4 /* array of response buffers */ 474#define CIFS_IOVEC 4 /* array of response buffers */
473 475
476/* Type of Request to SendReceive2 */
477#define CIFS_STD_OP 0 /* normal request timeout */
478#define CIFS_LONG_OP 1 /* long op (up to 45 sec, oplock time) */
479#define CIFS_VLONG_OP 2 /* sloow op - can take up to 180 seconds */
480#define CIFS_BLOCKING_OP 4 /* operation can block */
481#define CIFS_ASYNC_OP 8 /* do not wait for response */
482#define CIFS_TIMEOUT_MASK 0x00F /* only one of 5 above set in req */
483#define CIFS_LOG_ERROR 0x010 /* log NT STATUS if non-zero */
484#define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */
485#define CIFS_NO_RESP 0x040 /* no response buffer required */
486
474/* Security Flags: indicate type of session setup needed */ 487/* Security Flags: indicate type of session setup needed */
475#define CIFSSEC_MAY_SIGN 0x00001 488#define CIFSSEC_MAY_SIGN 0x00001
476#define CIFSSEC_MAY_NTLM 0x00002 489#define CIFSSEC_MAY_NTLM 0x00002
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index dd1d7c200ee6..8350eec49663 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -48,10 +48,11 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
48 struct smb_hdr * /* input */ , 48 struct smb_hdr * /* input */ ,
49 struct smb_hdr * /* out */ , 49 struct smb_hdr * /* out */ ,
50 int * /* bytes returned */ , const int long_op); 50 int * /* bytes returned */ , const int long_op);
51extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
52 struct smb_hdr *in_buf, int flags);
51extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 53extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
52 struct kvec *, int /* nvec to send */, 54 struct kvec *, int /* nvec to send */,
53 int * /* type of buf returned */ , const int long_op, 55 int * /* type of buf returned */ , const int flags);
54 const int logError /* whether to log status code*/ );
55extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 56extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
56 struct cifsTconInfo *, 57 struct cifsTconInfo *,
57 struct smb_hdr * /* input */ , 58 struct smb_hdr * /* input */ ,
@@ -76,8 +77,6 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
76extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 77extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
77 struct cifsSesInfo *ses, 78 struct cifsSesInfo *ses,
78 void **request_buf); 79 void **request_buf);
79extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo,
80 const char *hostname);
81extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 80extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
82 const int stage, 81 const int stage,
83 const struct nls_table *nls_cp); 82 const struct nls_table *nls_cp);
@@ -248,15 +247,15 @@ extern int CIFSSMBQueryReparseLinkInfo(const int xid,
248extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 247extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
249 const char *fileName, const int disposition, 248 const char *fileName, const int disposition,
250 const int access_flags, const int omode, 249 const int access_flags, const int omode,
251 __u16 * netfid, int *pOplock, FILE_ALL_INFO *, 250 __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
252 const struct nls_table *nls_codepage, int remap); 251 const struct nls_table *nls_codepage, int remap);
253extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 252extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
254 const char *fileName, const int disposition, 253 const char *fileName, const int disposition,
255 const int access_flags, const int omode, 254 const int access_flags, const int omode,
256 __u16 * netfid, int *pOplock, FILE_ALL_INFO *, 255 __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
257 const struct nls_table *nls_codepage, int remap); 256 const struct nls_table *nls_codepage, int remap);
258extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, 257extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
259 u32 posix_flags, __u64 mode, __u16 * netfid, 258 u32 posix_flags, __u64 mode, __u16 *netfid,
260 FILE_UNIX_BASIC_INFO *pRetData, 259 FILE_UNIX_BASIC_INFO *pRetData,
261 __u32 *pOplock, const char *name, 260 __u32 *pOplock, const char *name,
262 const struct nls_table *nls_codepage, int remap); 261 const struct nls_table *nls_codepage, int remap);
@@ -277,7 +276,7 @@ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
277 const __u64 offset, unsigned int *nbytes, 276 const __u64 offset, unsigned int *nbytes,
278 struct kvec *iov, const int nvec, const int long_op); 277 struct kvec *iov, const int nvec, const int long_op);
279extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 278extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
280 const unsigned char *searchName, __u64 * inode_number, 279 const unsigned char *searchName, __u64 *inode_number,
281 const struct nls_table *nls_codepage, 280 const struct nls_table *nls_codepage,
282 int remap_special_chars); 281 int remap_special_chars);
283extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, 282extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
@@ -352,5 +351,5 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
352 const char *local_acl, const int buflen, const int acl_type, 351 const char *local_acl, const int buflen, const int acl_type,
353 const struct nls_table *nls_codepage, int remap_special_chars); 352 const struct nls_table *nls_codepage, int remap_special_chars);
354extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 353extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
355 const int netfid, __u64 * pExtAttrBits, __u64 *pMask); 354 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
356#endif /* _CIFSPROTO_H */ 355#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 59d7b7c037ad..9e8a6bef029a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -698,9 +698,7 @@ int
698CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) 698CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
699{ 699{
700 struct smb_hdr *smb_buffer; 700 struct smb_hdr *smb_buffer;
701 struct smb_hdr *smb_buffer_response; /* BB removeme BB */
702 int rc = 0; 701 int rc = 0;
703 int length;
704 702
705 cFYI(1, ("In tree disconnect")); 703 cFYI(1, ("In tree disconnect"));
706 /* 704 /*
@@ -737,16 +735,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
737 if (rc) { 735 if (rc) {
738 up(&tcon->tconSem); 736 up(&tcon->tconSem);
739 return rc; 737 return rc;
740 } else {
741 smb_buffer_response = smb_buffer; /* BB removeme BB */
742 } 738 }
743 rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response, 739
744 &length, 0); 740 rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
745 if (rc) 741 if (rc)
746 cFYI(1, ("Tree disconnect failed %d", rc)); 742 cFYI(1, ("Tree disconnect failed %d", rc));
747 743
748 if (smb_buffer)
749 cifs_small_buf_release(smb_buffer);
750 up(&tcon->tconSem); 744 up(&tcon->tconSem);
751 745
752 /* No need to return error on this operation if tid invalidated and 746 /* No need to return error on this operation if tid invalidated and
@@ -760,10 +754,8 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
760int 754int
761CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) 755CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
762{ 756{
763 struct smb_hdr *smb_buffer_response;
764 LOGOFF_ANDX_REQ *pSMB; 757 LOGOFF_ANDX_REQ *pSMB;
765 int rc = 0; 758 int rc = 0;
766 int length;
767 759
768 cFYI(1, ("In SMBLogoff for session disconnect")); 760 cFYI(1, ("In SMBLogoff for session disconnect"));
769 if (ses) 761 if (ses)
@@ -782,8 +774,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
782 return rc; 774 return rc;
783 } 775 }
784 776
785 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
786
787 if (ses->server) { 777 if (ses->server) {
788 pSMB->hdr.Mid = GetNextMid(ses->server); 778 pSMB->hdr.Mid = GetNextMid(ses->server);
789 779
@@ -795,8 +785,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
795 pSMB->hdr.Uid = ses->Suid; 785 pSMB->hdr.Uid = ses->Suid;
796 786
797 pSMB->AndXCommand = 0xFF; 787 pSMB->AndXCommand = 0xFF;
798 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 788 rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
799 smb_buffer_response, &length, 0);
800 if (ses->server) { 789 if (ses->server) {
801 atomic_dec(&ses->server->socketUseCount); 790 atomic_dec(&ses->server->socketUseCount);
802 if (atomic_read(&ses->server->socketUseCount) == 0) { 791 if (atomic_read(&ses->server->socketUseCount) == 0) {
@@ -807,7 +796,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
807 } 796 }
808 } 797 }
809 up(&ses->sesSem); 798 up(&ses->sesSem);
810 cifs_small_buf_release(pSMB);
811 799
812 /* if session dead then we do not need to do ulogoff, 800 /* if session dead then we do not need to do ulogoff,
813 since server closed smb session, no sense reporting 801 since server closed smb session, no sense reporting
@@ -1255,7 +1243,7 @@ OldOpenRetry:
1255 pSMB->ByteCount = cpu_to_le16(count); 1243 pSMB->ByteCount = cpu_to_le16(count);
1256 /* long_op set to 1 to allow for oplock break timeouts */ 1244 /* long_op set to 1 to allow for oplock break timeouts */
1257 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1245 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1258 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1246 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
1259 cifs_stats_inc(&tcon->num_opens); 1247 cifs_stats_inc(&tcon->num_opens);
1260 if (rc) { 1248 if (rc) {
1261 cFYI(1, ("Error in Open = %d", rc)); 1249 cFYI(1, ("Error in Open = %d", rc));
@@ -1368,7 +1356,7 @@ openRetry:
1368 pSMB->ByteCount = cpu_to_le16(count); 1356 pSMB->ByteCount = cpu_to_le16(count);
1369 /* long_op set to 1 to allow for oplock break timeouts */ 1357 /* long_op set to 1 to allow for oplock break timeouts */
1370 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1358 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1371 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1359 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
1372 cifs_stats_inc(&tcon->num_opens); 1360 cifs_stats_inc(&tcon->num_opens);
1373 if (rc) { 1361 if (rc) {
1374 cFYI(1, ("Error in Open = %d", rc)); 1362 cFYI(1, ("Error in Open = %d", rc));
@@ -1446,7 +1434,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1446 iov[0].iov_base = (char *)pSMB; 1434 iov[0].iov_base = (char *)pSMB;
1447 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1435 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1448 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 1436 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1449 &resp_buf_type, 0 /* not long op */, 1 /* log err */ ); 1437 &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR);
1450 cifs_stats_inc(&tcon->num_reads); 1438 cifs_stats_inc(&tcon->num_reads);
1451 pSMBr = (READ_RSP *)iov[0].iov_base; 1439 pSMBr = (READ_RSP *)iov[0].iov_base;
1452 if (rc) { 1440 if (rc) {
@@ -1665,7 +1653,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1665 1653
1666 1654
1667 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 1655 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
1668 long_op, 0 /* do not log STATUS code */ ); 1656 long_op);
1669 cifs_stats_inc(&tcon->num_writes); 1657 cifs_stats_inc(&tcon->num_writes);
1670 if (rc) { 1658 if (rc) {
1671 cFYI(1, ("Send error Write2 = %d", rc)); 1659 cFYI(1, ("Send error Write2 = %d", rc));
@@ -1707,7 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1707 int timeout = 0; 1695 int timeout = 0;
1708 __u16 count; 1696 __u16 count;
1709 1697
1710 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d", waitFlag, numLock)); 1698 cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
1711 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1699 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1712 1700
1713 if (rc) 1701 if (rc)
@@ -1716,10 +1704,10 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1716 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ 1704 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1717 1705
1718 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1706 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1719 timeout = -1; /* no response expected */ 1707 timeout = CIFS_ASYNC_OP; /* no response expected */
1720 pSMB->Timeout = 0; 1708 pSMB->Timeout = 0;
1721 } else if (waitFlag == TRUE) { 1709 } else if (waitFlag == TRUE) {
1722 timeout = 3; /* blocking operation, no timeout */ 1710 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1723 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 1711 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1724 } else { 1712 } else {
1725 pSMB->Timeout = 0; 1713 pSMB->Timeout = 0;
@@ -1749,15 +1737,16 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1749 if (waitFlag) { 1737 if (waitFlag) {
1750 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1738 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1751 (struct smb_hdr *) pSMBr, &bytes_returned); 1739 (struct smb_hdr *) pSMBr, &bytes_returned);
1740 cifs_small_buf_release(pSMB);
1752 } else { 1741 } else {
1753 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1742 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
1754 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1743 timeout);
1744 /* SMB buffer freed by function above */
1755 } 1745 }
1756 cifs_stats_inc(&tcon->num_locks); 1746 cifs_stats_inc(&tcon->num_locks);
1757 if (rc) { 1747 if (rc) {
1758 cFYI(1, ("Send error in Lock = %d", rc)); 1748 cFYI(1, ("Send error in Lock = %d", rc));
1759 } 1749 }
1760 cifs_small_buf_release(pSMB);
1761 1750
1762 /* Note: On -EAGAIN error only caller can retry on handle based calls 1751 /* Note: On -EAGAIN error only caller can retry on handle based calls
1763 since file handle passed in no longer valid */ 1752 since file handle passed in no longer valid */
@@ -1776,7 +1765,9 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1776 int rc = 0; 1765 int rc = 0;
1777 int timeout = 0; 1766 int timeout = 0;
1778 int bytes_returned = 0; 1767 int bytes_returned = 0;
1768 int resp_buf_type = 0;
1779 __u16 params, param_offset, offset, byte_count, count; 1769 __u16 params, param_offset, offset, byte_count, count;
1770 struct kvec iov[1];
1780 1771
1781 cFYI(1, ("Posix Lock")); 1772 cFYI(1, ("Posix Lock"));
1782 1773
@@ -1818,7 +1809,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1818 1809
1819 parm_data->lock_type = cpu_to_le16(lock_type); 1810 parm_data->lock_type = cpu_to_le16(lock_type);
1820 if (waitFlag) { 1811 if (waitFlag) {
1821 timeout = 3; /* blocking operation, no timeout */ 1812 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1822 parm_data->lock_flags = cpu_to_le16(1); 1813 parm_data->lock_flags = cpu_to_le16(1);
1823 pSMB->Timeout = cpu_to_le32(-1); 1814 pSMB->Timeout = cpu_to_le32(-1);
1824 } else 1815 } else
@@ -1838,8 +1829,13 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1838 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1829 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1839 (struct smb_hdr *) pSMBr, &bytes_returned); 1830 (struct smb_hdr *) pSMBr, &bytes_returned);
1840 } else { 1831 } else {
1841 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1832 iov[0].iov_base = (char *)pSMB;
1842 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1833 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1834 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1835 &resp_buf_type, timeout);
1836 pSMB = NULL; /* request buf already freed by SendReceive2. Do
1837 not try to free it twice below on exit */
1838 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
1843 } 1839 }
1844 1840
1845 if (rc) { 1841 if (rc) {
@@ -1874,6 +1870,11 @@ plk_err_exit:
1874 if (pSMB) 1870 if (pSMB)
1875 cifs_small_buf_release(pSMB); 1871 cifs_small_buf_release(pSMB);
1876 1872
1873 if (resp_buf_type == CIFS_SMALL_BUFFER)
1874 cifs_small_buf_release(iov[0].iov_base);
1875 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1876 cifs_buf_release(iov[0].iov_base);
1877
1877 /* Note: On -EAGAIN error only caller can retry on handle based calls 1878 /* Note: On -EAGAIN error only caller can retry on handle based calls
1878 since file handle passed in no longer valid */ 1879 since file handle passed in no longer valid */
1879 1880
@@ -1886,8 +1887,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1886{ 1887{
1887 int rc = 0; 1888 int rc = 0;
1888 CLOSE_REQ *pSMB = NULL; 1889 CLOSE_REQ *pSMB = NULL;
1889 CLOSE_RSP *pSMBr = NULL;
1890 int bytes_returned;
1891 cFYI(1, ("In CIFSSMBClose")); 1890 cFYI(1, ("In CIFSSMBClose"));
1892 1891
1893/* do not retry on dead session on close */ 1892/* do not retry on dead session on close */
@@ -1897,13 +1896,10 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1897 if (rc) 1896 if (rc)
1898 return rc; 1897 return rc;
1899 1898
1900 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
1901
1902 pSMB->FileID = (__u16) smb_file_id; 1899 pSMB->FileID = (__u16) smb_file_id;
1903 pSMB->LastWriteTime = 0xFFFFFFFF; 1900 pSMB->LastWriteTime = 0xFFFFFFFF;
1904 pSMB->ByteCount = 0; 1901 pSMB->ByteCount = 0;
1905 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1902 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
1906 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1907 cifs_stats_inc(&tcon->num_closes); 1903 cifs_stats_inc(&tcon->num_closes);
1908 if (rc) { 1904 if (rc) {
1909 if (rc != -EINTR) { 1905 if (rc != -EINTR) {
@@ -1912,8 +1908,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1912 } 1908 }
1913 } 1909 }
1914 1910
1915 cifs_small_buf_release(pSMB);
1916
1917 /* Since session is dead, file will be closed on server already */ 1911 /* Since session is dead, file will be closed on server already */
1918 if (rc == -EAGAIN) 1912 if (rc == -EAGAIN)
1919 rc = 0; 1913 rc = 0;
@@ -3102,7 +3096,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3102 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 3096 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
3103 3097
3104 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3098 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3105 0 /* not long op */, 0 /* do not log STATUS codes */ ); 3099 CIFS_STD_OP);
3106 cifs_stats_inc(&tcon->num_acl_get); 3100 cifs_stats_inc(&tcon->num_acl_get);
3107 if (rc) { 3101 if (rc) {
3108 cFYI(1, ("Send error in QuerySecDesc = %d", rc)); 3102 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
@@ -3763,8 +3757,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3763{ 3757{
3764 int rc = 0; 3758 int rc = 0;
3765 FINDCLOSE_REQ *pSMB = NULL; 3759 FINDCLOSE_REQ *pSMB = NULL;
3766 CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
3767 int bytes_returned;
3768 3760
3769 cFYI(1, ("In CIFSSMBFindClose")); 3761 cFYI(1, ("In CIFSSMBFindClose"));
3770 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 3762 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
@@ -3776,16 +3768,13 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3776 if (rc) 3768 if (rc)
3777 return rc; 3769 return rc;
3778 3770
3779 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
3780 pSMB->FileID = searchHandle; 3771 pSMB->FileID = searchHandle;
3781 pSMB->ByteCount = 0; 3772 pSMB->ByteCount = 0;
3782 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3773 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
3783 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3784 if (rc) { 3774 if (rc) {
3785 cERROR(1, ("Send error in FindClose = %d", rc)); 3775 cERROR(1, ("Send error in FindClose = %d", rc));
3786 } 3776 }
3787 cifs_stats_inc(&tcon->num_fclose); 3777 cifs_stats_inc(&tcon->num_fclose);
3788 cifs_small_buf_release(pSMB);
3789 3778
3790 /* Since session is dead, search handle closed on server already */ 3779 /* Since session is dead, search handle closed on server already */
3791 if (rc == -EAGAIN) 3780 if (rc == -EAGAIN)
@@ -4707,11 +4696,9 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4707 __u16 fid, __u32 pid_of_opener, int SetAllocation) 4696 __u16 fid, __u32 pid_of_opener, int SetAllocation)
4708{ 4697{
4709 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4698 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4710 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
4711 char *data_offset; 4699 char *data_offset;
4712 struct file_end_of_file_info *parm_data; 4700 struct file_end_of_file_info *parm_data;
4713 int rc = 0; 4701 int rc = 0;
4714 int bytes_returned = 0;
4715 __u16 params, param_offset, offset, byte_count, count; 4702 __u16 params, param_offset, offset, byte_count, count;
4716 4703
4717 cFYI(1, ("SetFileSize (via SetFileInfo) %lld", 4704 cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
@@ -4721,8 +4708,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4721 if (rc) 4708 if (rc)
4722 return rc; 4709 return rc;
4723 4710
4724 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
4725
4726 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4711 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4727 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 4712 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
4728 4713
@@ -4773,17 +4758,13 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4773 pSMB->Reserved4 = 0; 4758 pSMB->Reserved4 = 0;
4774 pSMB->hdr.smb_buf_length += byte_count; 4759 pSMB->hdr.smb_buf_length += byte_count;
4775 pSMB->ByteCount = cpu_to_le16(byte_count); 4760 pSMB->ByteCount = cpu_to_le16(byte_count);
4776 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4761 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4777 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4778 if (rc) { 4762 if (rc) {
4779 cFYI(1, 4763 cFYI(1,
4780 ("Send error in SetFileInfo (SetFileSize) = %d", 4764 ("Send error in SetFileInfo (SetFileSize) = %d",
4781 rc)); 4765 rc));
4782 } 4766 }
4783 4767
4784 if (pSMB)
4785 cifs_small_buf_release(pSMB);
4786
4787 /* Note: On -EAGAIN error only caller can retry on handle based calls 4768 /* Note: On -EAGAIN error only caller can retry on handle based calls
4788 since file handle passed in no longer valid */ 4769 since file handle passed in no longer valid */
4789 4770
@@ -4801,10 +4782,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4801 const FILE_BASIC_INFO *data, __u16 fid) 4782 const FILE_BASIC_INFO *data, __u16 fid)
4802{ 4783{
4803 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4784 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4804 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
4805 char *data_offset; 4785 char *data_offset;
4806 int rc = 0; 4786 int rc = 0;
4807 int bytes_returned = 0;
4808 __u16 params, param_offset, offset, byte_count, count; 4787 __u16 params, param_offset, offset, byte_count, count;
4809 4788
4810 cFYI(1, ("Set Times (via SetFileInfo)")); 4789 cFYI(1, ("Set Times (via SetFileInfo)"));
@@ -4813,8 +4792,6 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4813 if (rc) 4792 if (rc)
4814 return rc; 4793 return rc;
4815 4794
4816 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
4817
4818 /* At this point there is no need to override the current pid 4795 /* At this point there is no need to override the current pid
4819 with the pid of the opener, but that could change if we someday 4796 with the pid of the opener, but that could change if we someday
4820 use an existing handle (rather than opening one on the fly) */ 4797 use an existing handle (rather than opening one on the fly) */
@@ -4854,14 +4831,11 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4854 pSMB->hdr.smb_buf_length += byte_count; 4831 pSMB->hdr.smb_buf_length += byte_count;
4855 pSMB->ByteCount = cpu_to_le16(byte_count); 4832 pSMB->ByteCount = cpu_to_le16(byte_count);
4856 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 4833 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
4857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4834 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4859 if (rc) { 4835 if (rc) {
4860 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); 4836 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
4861 } 4837 }
4862 4838
4863 cifs_small_buf_release(pSMB);
4864
4865 /* Note: On -EAGAIN error only caller can retry on handle based calls 4839 /* Note: On -EAGAIN error only caller can retry on handle based calls
4866 since file handle passed in no longer valid */ 4840 since file handle passed in no longer valid */
4867 4841
@@ -5152,7 +5126,8 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5152 pSMB->ByteCount = 0; 5126 pSMB->ByteCount = 0;
5153 5127
5154 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5128 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5155 (struct smb_hdr *) pSMBr, &bytes_returned, -1); 5129 (struct smb_hdr *)pSMBr, &bytes_returned,
5130 CIFS_ASYNC_OP);
5156 if (rc) { 5131 if (rc) {
5157 cFYI(1, ("Error in Notify = %d", rc)); 5132 cFYI(1, ("Error in Notify = %d", rc));
5158 } else { 5133 } else {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c52a76ff4bb9..fd9147cdb5a9 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -438,9 +438,9 @@ incomplete_rcv:
438 csocket = server->ssocket; 438 csocket = server->ssocket;
439 wake_up(&server->response_q); 439 wake_up(&server->response_q);
440 continue; 440 continue;
441 } else if (length < 4) { 441 } else if (length < pdu_length) {
442 cFYI(1, ("less than four bytes received (%d bytes)", 442 cFYI(1, ("requested %d bytes but only got %d bytes",
443 length)); 443 pdu_length, length));
444 pdu_length -= length; 444 pdu_length -= length;
445 msleep(1); 445 msleep(1);
446 goto incomplete_rcv; 446 goto incomplete_rcv;
@@ -752,6 +752,7 @@ multi_t2_fnd:
752 } 752 }
753 write_unlock(&GlobalSMBSeslock); 753 write_unlock(&GlobalSMBSeslock);
754 754
755 kfree(server->hostname);
755 kfree(server); 756 kfree(server);
756 if (length > 0) 757 if (length > 0)
757 mempool_resize(cifs_req_poolp, length + cifs_min_rcv, 758 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
@@ -760,6 +761,34 @@ multi_t2_fnd:
760 return 0; 761 return 0;
761} 762}
762 763
764/* extract the host portion of the UNC string */
765static char *
766extract_hostname(const char *unc)
767{
768 const char *src;
769 char *dst, *delim;
770 unsigned int len;
771
772 /* skip double chars at beginning of string */
773 /* BB: check validity of these bytes? */
774 src = unc + 2;
775
776 /* delimiter between hostname and sharename is always '\\' now */
777 delim = strchr(src, '\\');
778 if (!delim)
779 return ERR_PTR(-EINVAL);
780
781 len = delim - src;
782 dst = kmalloc((len + 1), GFP_KERNEL);
783 if (dst == NULL)
784 return ERR_PTR(-ENOMEM);
785
786 memcpy(dst, src, len);
787 dst[len] = '\0';
788
789 return dst;
790}
791
763static int 792static int
764cifs_parse_mount_options(char *options, const char *devname, 793cifs_parse_mount_options(char *options, const char *devname,
765 struct smb_vol *vol) 794 struct smb_vol *vol)
@@ -1781,11 +1810,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1781 1810
1782 memset(&volume_info, 0, sizeof(struct smb_vol)); 1811 memset(&volume_info, 0, sizeof(struct smb_vol));
1783 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1812 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1784 kfree(volume_info.UNC); 1813 rc = -EINVAL;
1785 kfree(volume_info.password); 1814 goto out;
1786 kfree(volume_info.prepath);
1787 FreeXid(xid);
1788 return -EINVAL;
1789 } 1815 }
1790 1816
1791 if (volume_info.nullauth) { 1817 if (volume_info.nullauth) {
@@ -1798,11 +1824,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1798 cifserror("No username specified"); 1824 cifserror("No username specified");
1799 /* In userspace mount helper we can get user name from alternate 1825 /* In userspace mount helper we can get user name from alternate
1800 locations such as env variables and files on disk */ 1826 locations such as env variables and files on disk */
1801 kfree(volume_info.UNC); 1827 rc = -EINVAL;
1802 kfree(volume_info.password); 1828 goto out;
1803 kfree(volume_info.prepath);
1804 FreeXid(xid);
1805 return -EINVAL;
1806 } 1829 }
1807 1830
1808 if (volume_info.UNCip && volume_info.UNC) { 1831 if (volume_info.UNCip && volume_info.UNC) {
@@ -1821,11 +1844,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1821 1844
1822 if (rc <= 0) { 1845 if (rc <= 0) {
1823 /* we failed translating address */ 1846 /* we failed translating address */
1824 kfree(volume_info.UNC); 1847 rc = -EINVAL;
1825 kfree(volume_info.password); 1848 goto out;
1826 kfree(volume_info.prepath);
1827 FreeXid(xid);
1828 return -EINVAL;
1829 } 1849 }
1830 1850
1831 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip)); 1851 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
@@ -1835,20 +1855,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1835 /* BB using ip addr as server name to connect to the 1855 /* BB using ip addr as server name to connect to the
1836 DFS root below */ 1856 DFS root below */
1837 cERROR(1, ("Connecting to DFS root not implemented yet")); 1857 cERROR(1, ("Connecting to DFS root not implemented yet"));
1838 kfree(volume_info.UNC); 1858 rc = -EINVAL;
1839 kfree(volume_info.password); 1859 goto out;
1840 kfree(volume_info.prepath);
1841 FreeXid(xid);
1842 return -EINVAL;
1843 } else /* which servers DFS root would we conect to */ { 1860 } else /* which servers DFS root would we conect to */ {
1844 cERROR(1, 1861 cERROR(1,
1845 ("CIFS mount error: No UNC path (e.g. -o " 1862 ("CIFS mount error: No UNC path (e.g. -o "
1846 "unc=//192.168.1.100/public) specified")); 1863 "unc=//192.168.1.100/public) specified"));
1847 kfree(volume_info.UNC); 1864 rc = -EINVAL;
1848 kfree(volume_info.password); 1865 goto out;
1849 kfree(volume_info.prepath);
1850 FreeXid(xid);
1851 return -EINVAL;
1852 } 1866 }
1853 1867
1854 /* this is needed for ASCII cp to Unicode converts */ 1868 /* this is needed for ASCII cp to Unicode converts */
@@ -1860,11 +1874,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1860 if (cifs_sb->local_nls == NULL) { 1874 if (cifs_sb->local_nls == NULL) {
1861 cERROR(1, ("CIFS mount error: iocharset %s not found", 1875 cERROR(1, ("CIFS mount error: iocharset %s not found",
1862 volume_info.iocharset)); 1876 volume_info.iocharset));
1863 kfree(volume_info.UNC); 1877 rc = -ELIBACC;
1864 kfree(volume_info.password); 1878 goto out;
1865 kfree(volume_info.prepath);
1866 FreeXid(xid);
1867 return -ELIBACC;
1868 } 1879 }
1869 } 1880 }
1870 1881
@@ -1878,11 +1889,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1878 &sin_server6.sin6_addr, 1889 &sin_server6.sin6_addr,
1879 volume_info.username, &srvTcp); 1890 volume_info.username, &srvTcp);
1880 } else { 1891 } else {
1881 kfree(volume_info.UNC); 1892 rc = -EINVAL;
1882 kfree(volume_info.password); 1893 goto out;
1883 kfree(volume_info.prepath);
1884 FreeXid(xid);
1885 return -EINVAL;
1886 } 1894 }
1887 1895
1888 if (srvTcp) { 1896 if (srvTcp) {
@@ -1906,22 +1914,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1906 "Aborting operation")); 1914 "Aborting operation"));
1907 if (csocket != NULL) 1915 if (csocket != NULL)
1908 sock_release(csocket); 1916 sock_release(csocket);
1909 kfree(volume_info.UNC); 1917 goto out;
1910 kfree(volume_info.password);
1911 kfree(volume_info.prepath);
1912 FreeXid(xid);
1913 return rc;
1914 } 1918 }
1915 1919
1916 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); 1920 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1917 if (!srvTcp) { 1921 if (!srvTcp) {
1918 rc = -ENOMEM; 1922 rc = -ENOMEM;
1919 sock_release(csocket); 1923 sock_release(csocket);
1920 kfree(volume_info.UNC); 1924 goto out;
1921 kfree(volume_info.password);
1922 kfree(volume_info.prepath);
1923 FreeXid(xid);
1924 return rc;
1925 } else { 1925 } else {
1926 memcpy(&srvTcp->addr.sockAddr, &sin_server, 1926 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1927 sizeof(struct sockaddr_in)); 1927 sizeof(struct sockaddr_in));
@@ -1929,6 +1929,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1929 /* BB Add code for ipv6 case too */ 1929 /* BB Add code for ipv6 case too */
1930 srvTcp->ssocket = csocket; 1930 srvTcp->ssocket = csocket;
1931 srvTcp->protocolType = IPV4; 1931 srvTcp->protocolType = IPV4;
1932 srvTcp->hostname = extract_hostname(volume_info.UNC);
1933 if (IS_ERR(srvTcp->hostname)) {
1934 rc = PTR_ERR(srvTcp->hostname);
1935 sock_release(csocket);
1936 goto out;
1937 }
1932 init_waitqueue_head(&srvTcp->response_q); 1938 init_waitqueue_head(&srvTcp->response_q);
1933 init_waitqueue_head(&srvTcp->request_q); 1939 init_waitqueue_head(&srvTcp->request_q);
1934 INIT_LIST_HEAD(&srvTcp->pending_mid_q); 1940 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
@@ -1938,16 +1944,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1938 srvTcp->tcpStatus = CifsNew; 1944 srvTcp->tcpStatus = CifsNew;
1939 init_MUTEX(&srvTcp->tcpSem); 1945 init_MUTEX(&srvTcp->tcpSem);
1940 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); 1946 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1941 if ( IS_ERR(srvTcp->tsk) ) { 1947 if (IS_ERR(srvTcp->tsk)) {
1942 rc = PTR_ERR(srvTcp->tsk); 1948 rc = PTR_ERR(srvTcp->tsk);
1943 cERROR(1, ("error %d create cifsd thread", rc)); 1949 cERROR(1, ("error %d create cifsd thread", rc));
1944 srvTcp->tsk = NULL; 1950 srvTcp->tsk = NULL;
1945 sock_release(csocket); 1951 sock_release(csocket);
1946 kfree(volume_info.UNC); 1952 kfree(srvTcp->hostname);
1947 kfree(volume_info.password); 1953 goto out;
1948 kfree(volume_info.prepath);
1949 FreeXid(xid);
1950 return rc;
1951 } 1954 }
1952 wait_for_completion(&cifsd_complete); 1955 wait_for_completion(&cifsd_complete);
1953 rc = 0; 1956 rc = 0;
@@ -1962,8 +1965,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1962 if (existingCifsSes) { 1965 if (existingCifsSes) {
1963 pSesInfo = existingCifsSes; 1966 pSesInfo = existingCifsSes;
1964 cFYI(1, ("Existing smb sess found")); 1967 cFYI(1, ("Existing smb sess found"));
1965 kfree(volume_info.password);
1966 /* volume_info.UNC freed at end of function */
1967 } else if (!rc) { 1968 } else if (!rc) {
1968 cFYI(1, ("Existing smb sess not found")); 1969 cFYI(1, ("Existing smb sess not found"));
1969 pSesInfo = sesInfoAlloc(); 1970 pSesInfo = sesInfoAlloc();
@@ -1977,8 +1978,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1977 1978
1978 if (!rc) { 1979 if (!rc) {
1979 /* volume_info.password freed at unmount */ 1980 /* volume_info.password freed at unmount */
1980 if (volume_info.password) 1981 if (volume_info.password) {
1981 pSesInfo->password = volume_info.password; 1982 pSesInfo->password = volume_info.password;
1983 /* set to NULL to prevent freeing on exit */
1984 volume_info.password = NULL;
1985 }
1982 if (volume_info.username) 1986 if (volume_info.username)
1983 strncpy(pSesInfo->userName, 1987 strncpy(pSesInfo->userName,
1984 volume_info.username, 1988 volume_info.username,
@@ -2000,8 +2004,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2000 up(&pSesInfo->sesSem); 2004 up(&pSesInfo->sesSem);
2001 if (!rc) 2005 if (!rc)
2002 atomic_inc(&srvTcp->socketUseCount); 2006 atomic_inc(&srvTcp->socketUseCount);
2003 } else 2007 }
2004 kfree(volume_info.password);
2005 } 2008 }
2006 2009
2007 /* search for existing tcon to this server share */ 2010 /* search for existing tcon to this server share */
@@ -2106,9 +2109,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2106 "", cifs_sb->local_nls, 2109 "", cifs_sb->local_nls,
2107 cifs_sb->mnt_cifs_flags & 2110 cifs_sb->mnt_cifs_flags &
2108 CIFS_MOUNT_MAP_SPECIAL_CHR); 2111 CIFS_MOUNT_MAP_SPECIAL_CHR);
2109 kfree(volume_info.UNC); 2112 rc = -ENODEV;
2110 FreeXid(xid); 2113 goto out;
2111 return -ENODEV;
2112 } else { 2114 } else {
2113 /* BB Do we need to wrap sesSem around 2115 /* BB Do we need to wrap sesSem around
2114 * this TCon call and Unix SetFS as 2116 * this TCon call and Unix SetFS as
@@ -2231,6 +2233,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2231 (in which case it is not needed anymore) but when new sesion is created 2233 (in which case it is not needed anymore) but when new sesion is created
2232 the password ptr is put in the new session structure (in which case the 2234 the password ptr is put in the new session structure (in which case the
2233 password will be freed at unmount time) */ 2235 password will be freed at unmount time) */
2236out:
2237 /* zero out password before freeing */
2238 if (volume_info.password != NULL) {
2239 memset(volume_info.password, 0, strlen(volume_info.password));
2240 kfree(volume_info.password);
2241 }
2234 kfree(volume_info.UNC); 2242 kfree(volume_info.UNC);
2235 kfree(volume_info.prepath); 2243 kfree(volume_info.prepath);
2236 FreeXid(xid); 2244 FreeXid(xid);
@@ -2374,7 +2382,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2374 pSMB->req_no_secext.ByteCount = cpu_to_le16(count); 2382 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2375 2383
2376 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2384 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2377 &bytes_returned, 1); 2385 &bytes_returned, CIFS_LONG_OP);
2378 if (rc) { 2386 if (rc) {
2379/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */ 2387/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2380 } else if ((smb_buffer_response->WordCount == 3) 2388 } else if ((smb_buffer_response->WordCount == 3)
@@ -2678,7 +2686,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2678 pSMB->req.ByteCount = cpu_to_le16(count); 2686 pSMB->req.ByteCount = cpu_to_le16(count);
2679 2687
2680 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2688 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2681 &bytes_returned, 1); 2689 &bytes_returned, CIFS_LONG_OP);
2682 2690
2683 if (smb_buffer_response->Status.CifsError == 2691 if (smb_buffer_response->Status.CifsError ==
2684 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)) 2692 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
@@ -3105,7 +3113,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3105 pSMB->req.ByteCount = cpu_to_le16(count); 3113 pSMB->req.ByteCount = cpu_to_le16(count);
3106 3114
3107 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 3115 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3108 &bytes_returned, 1); 3116 &bytes_returned, CIFS_LONG_OP);
3109 if (rc) { 3117 if (rc) {
3110/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */ 3118/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3111 } else if ((smb_buffer_response->WordCount == 3) || 3119 } else if ((smb_buffer_response->WordCount == 3) ||
@@ -3381,7 +3389,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3381 pSMB->hdr.smb_buf_length += count; 3389 pSMB->hdr.smb_buf_length += count;
3382 pSMB->ByteCount = cpu_to_le16(count); 3390 pSMB->ByteCount = cpu_to_le16(count);
3383 3391
3384 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0); 3392 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3393 CIFS_STD_OP);
3385 3394
3386 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */ 3395 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3387 /* above now done in SendReceive */ 3396 /* above now done in SendReceive */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 68ad4ca0cfa3..dd26e2759b17 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -130,7 +130,9 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
130 if (file->f_path.dentry->d_inode->i_mapping) { 130 if (file->f_path.dentry->d_inode->i_mapping) {
131 /* BB no need to lock inode until after invalidate 131 /* BB no need to lock inode until after invalidate
132 since namei code should already have it locked? */ 132 since namei code should already have it locked? */
133 filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); 133 rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
134 if (rc != 0)
135 CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
134 } 136 }
135 cFYI(1, ("invalidating remote inode since open detected it " 137 cFYI(1, ("invalidating remote inode since open detected it "
136 "changed")); 138 "changed"));
@@ -425,7 +427,9 @@ reopen_error_exit:
425 pCifsInode = CIFS_I(inode); 427 pCifsInode = CIFS_I(inode);
426 if (pCifsInode) { 428 if (pCifsInode) {
427 if (can_flush) { 429 if (can_flush) {
428 filemap_write_and_wait(inode->i_mapping); 430 rc = filemap_write_and_wait(inode->i_mapping);
431 if (rc != 0)
432 CIFS_I(inode)->write_behind_rc = rc;
429 /* temporarily disable caching while we 433 /* temporarily disable caching while we
430 go to server to get inode info */ 434 go to server to get inode info */
431 pCifsInode->clientCanCacheAll = FALSE; 435 pCifsInode->clientCanCacheAll = FALSE;
@@ -835,9 +839,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
835 xid = GetXid(); 839 xid = GetXid();
836 840
837 if (*poffset > file->f_path.dentry->d_inode->i_size) 841 if (*poffset > file->f_path.dentry->d_inode->i_size)
838 long_op = 2; /* writes past end of file can take a long time */ 842 long_op = CIFS_VLONG_OP; /* writes past EOF take long time */
839 else 843 else
840 long_op = 1; 844 long_op = CIFS_LONG_OP;
841 845
842 for (total_written = 0; write_size > total_written; 846 for (total_written = 0; write_size > total_written;
843 total_written += bytes_written) { 847 total_written += bytes_written) {
@@ -884,7 +888,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
884 } 888 }
885 } else 889 } else
886 *poffset += bytes_written; 890 *poffset += bytes_written;
887 long_op = FALSE; /* subsequent writes fast - 891 long_op = CIFS_STD_OP; /* subsequent writes fast -
888 15 seconds is plenty */ 892 15 seconds is plenty */
889 } 893 }
890 894
@@ -934,9 +938,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
934 xid = GetXid(); 938 xid = GetXid();
935 939
936 if (*poffset > file->f_path.dentry->d_inode->i_size) 940 if (*poffset > file->f_path.dentry->d_inode->i_size)
937 long_op = 2; /* writes past end of file can take a long time */ 941 long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */
938 else 942 else
939 long_op = 1; 943 long_op = CIFS_LONG_OP;
940 944
941 for (total_written = 0; write_size > total_written; 945 for (total_written = 0; write_size > total_written;
942 total_written += bytes_written) { 946 total_written += bytes_written) {
@@ -1002,7 +1006,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1002 } 1006 }
1003 } else 1007 } else
1004 *poffset += bytes_written; 1008 *poffset += bytes_written;
1005 long_op = FALSE; /* subsequent writes fast - 1009 long_op = CIFS_STD_OP; /* subsequent writes fast -
1006 15 seconds is plenty */ 1010 15 seconds is plenty */
1007 } 1011 }
1008 1012
@@ -1087,11 +1091,11 @@ refind_writable:
1087 read_unlock(&GlobalSMBSeslock); 1091 read_unlock(&GlobalSMBSeslock);
1088 return open_file; 1092 return open_file;
1089 } 1093 }
1090 1094
1091 read_unlock(&GlobalSMBSeslock); 1095 read_unlock(&GlobalSMBSeslock);
1092 /* Had to unlock since following call can block */ 1096 /* Had to unlock since following call can block */
1093 rc = cifs_reopen_file(open_file->pfile, FALSE); 1097 rc = cifs_reopen_file(open_file->pfile, FALSE);
1094 if (!rc) { 1098 if (!rc) {
1095 if (!open_file->closePend) 1099 if (!open_file->closePend)
1096 return open_file; 1100 return open_file;
1097 else { /* start over in case this was deleted */ 1101 else { /* start over in case this was deleted */
@@ -1114,7 +1118,7 @@ refind_writable:
1114 /* can not use this handle, no write 1118 /* can not use this handle, no write
1115 pending on this one after all */ 1119 pending on this one after all */
1116 atomic_dec(&open_file->wrtPending); 1120 atomic_dec(&open_file->wrtPending);
1117 1121
1118 if (open_file->closePend) /* list could have changed */ 1122 if (open_file->closePend) /* list could have changed */
1119 goto refind_writable; 1123 goto refind_writable;
1120 /* else we simply continue to the next entry. Thus 1124 /* else we simply continue to the next entry. Thus
@@ -1360,14 +1364,17 @@ retry:
1360 open_file->netfid, 1364 open_file->netfid,
1361 bytes_to_write, offset, 1365 bytes_to_write, offset,
1362 &bytes_written, iov, n_iov, 1366 &bytes_written, iov, n_iov,
1363 1); 1367 CIFS_LONG_OP);
1364 atomic_dec(&open_file->wrtPending); 1368 atomic_dec(&open_file->wrtPending);
1365 if (rc || bytes_written < bytes_to_write) { 1369 if (rc || bytes_written < bytes_to_write) {
1366 cERROR(1, ("Write2 ret %d, wrote %d", 1370 cERROR(1, ("Write2 ret %d, wrote %d",
1367 rc, bytes_written)); 1371 rc, bytes_written));
1368 /* BB what if continued retry is 1372 /* BB what if continued retry is
1369 requested via mount flags? */ 1373 requested via mount flags? */
1370 set_bit(AS_EIO, &mapping->flags); 1374 if (rc == -ENOSPC)
1375 set_bit(AS_ENOSPC, &mapping->flags);
1376 else
1377 set_bit(AS_EIO, &mapping->flags);
1371 } else { 1378 } else {
1372 cifs_stats_bytes_written(cifs_sb->tcon, 1379 cifs_stats_bytes_written(cifs_sb->tcon,
1373 bytes_written); 1380 bytes_written);
@@ -1499,9 +1506,11 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1499 cFYI(1, ("Sync file - name: %s datasync: 0x%x", 1506 cFYI(1, ("Sync file - name: %s datasync: 0x%x",
1500 dentry->d_name.name, datasync)); 1507 dentry->d_name.name, datasync));
1501 1508
1502 rc = filemap_fdatawrite(inode->i_mapping); 1509 rc = filemap_write_and_wait(inode->i_mapping);
1503 if (rc == 0) 1510 if (rc == 0) {
1511 rc = CIFS_I(inode)->write_behind_rc;
1504 CIFS_I(inode)->write_behind_rc = 0; 1512 CIFS_I(inode)->write_behind_rc = 0;
1513 }
1505 FreeXid(xid); 1514 FreeXid(xid);
1506 return rc; 1515 return rc;
1507} 1516}
@@ -1553,8 +1562,11 @@ int cifs_flush(struct file *file, fl_owner_t id)
1553 filemapfdatawrite appears easier for the time being */ 1562 filemapfdatawrite appears easier for the time being */
1554 1563
1555 rc = filemap_fdatawrite(inode->i_mapping); 1564 rc = filemap_fdatawrite(inode->i_mapping);
1556 if (!rc) /* reset wb rc if we were able to write out dirty pages */ 1565 /* reset wb rc if we were able to write out dirty pages */
1566 if (!rc) {
1567 rc = CIFS_I(inode)->write_behind_rc;
1557 CIFS_I(inode)->write_behind_rc = 0; 1568 CIFS_I(inode)->write_behind_rc = 0;
1569 }
1558 1570
1559 cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc)); 1571 cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));
1560 1572
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 7d907e84e032..e915eb1d2e66 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1233,7 +1233,7 @@ cifs_rename_exit:
1233int cifs_revalidate(struct dentry *direntry) 1233int cifs_revalidate(struct dentry *direntry)
1234{ 1234{
1235 int xid; 1235 int xid;
1236 int rc = 0; 1236 int rc = 0, wbrc = 0;
1237 char *full_path; 1237 char *full_path;
1238 struct cifs_sb_info *cifs_sb; 1238 struct cifs_sb_info *cifs_sb;
1239 struct cifsInodeInfo *cifsInode; 1239 struct cifsInodeInfo *cifsInode;
@@ -1333,7 +1333,9 @@ int cifs_revalidate(struct dentry *direntry)
1333 if (direntry->d_inode->i_mapping) { 1333 if (direntry->d_inode->i_mapping) {
1334 /* do we need to lock inode until after invalidate completes 1334 /* do we need to lock inode until after invalidate completes
1335 below? */ 1335 below? */
1336 filemap_fdatawrite(direntry->d_inode->i_mapping); 1336 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1337 if (wbrc)
1338 CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1337 } 1339 }
1338 if (invalidate_inode) { 1340 if (invalidate_inode) {
1339 /* shrink_dcache not necessary now that cifs dentry ops 1341 /* shrink_dcache not necessary now that cifs dentry ops
@@ -1342,7 +1344,9 @@ int cifs_revalidate(struct dentry *direntry)
1342 shrink_dcache_parent(direntry); */ 1344 shrink_dcache_parent(direntry); */
1343 if (S_ISREG(direntry->d_inode->i_mode)) { 1345 if (S_ISREG(direntry->d_inode->i_mode)) {
1344 if (direntry->d_inode->i_mapping) 1346 if (direntry->d_inode->i_mapping)
1345 filemap_fdatawait(direntry->d_inode->i_mapping); 1347 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1348 if (wbrc)
1349 CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1346 /* may eventually have to do this for open files too */ 1350 /* may eventually have to do this for open files too */
1347 if (list_empty(&(cifsInode->openFileList))) { 1351 if (list_empty(&(cifsInode->openFileList))) {
1348 /* changed on server - flush read ahead pages */ 1352 /* changed on server - flush read ahead pages */
@@ -1485,10 +1489,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1485 1489
1486 /* BB check if we need to refresh inode from server now ? BB */ 1490 /* BB check if we need to refresh inode from server now ? BB */
1487 1491
1488 /* need to flush data before changing file size on server */
1489 filemap_write_and_wait(direntry->d_inode->i_mapping);
1490
1491 if (attrs->ia_valid & ATTR_SIZE) { 1492 if (attrs->ia_valid & ATTR_SIZE) {
1493 /*
1494 Flush data before changing file size on server. If the
1495 flush returns error, store it to report later and continue.
1496 BB: This should be smarter. Why bother flushing pages that
1497 will be truncated anyway? Also, should we error out here if
1498 the flush returns error?
1499 */
1500 rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
1501 if (rc != 0) {
1502 CIFS_I(direntry->d_inode)->write_behind_rc = rc;
1503 rc = 0;
1504 }
1505
1492 /* To avoid spurious oplock breaks from server, in the case of 1506 /* To avoid spurious oplock breaks from server, in the case of
1493 inodes that we already have open, avoid doing path based 1507 inodes that we already have open, avoid doing path based
1494 setting of file size if we can do it by handle. 1508 setting of file size if we can do it by handle.
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 899dc6078d9a..d0cb469daab7 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -29,6 +29,7 @@
29#include "ntlmssp.h" 29#include "ntlmssp.h"
30#include "nterr.h" 30#include "nterr.h"
31#include <linux/utsname.h> 31#include <linux/utsname.h>
32#include "cifs_spnego.h"
32 33
33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 34extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
34 unsigned char *p24); 35 unsigned char *p24);
@@ -340,11 +341,12 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
340 SESSION_SETUP_ANDX *pSMB; 341 SESSION_SETUP_ANDX *pSMB;
341 __u32 capabilities; 342 __u32 capabilities;
342 int count; 343 int count;
343 int resp_buf_type = 0; 344 int resp_buf_type;
344 struct kvec iov[2]; 345 struct kvec iov[3];
345 enum securityEnum type; 346 enum securityEnum type;
346 __u16 action; 347 __u16 action;
347 int bytes_remaining; 348 int bytes_remaining;
349 struct key *spnego_key = NULL;
348 350
349 if (ses == NULL) 351 if (ses == NULL)
350 return -EINVAL; 352 return -EINVAL;
@@ -377,24 +379,32 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
377 379
378 capabilities = cifs_ssetup_hdr(ses, pSMB); 380 capabilities = cifs_ssetup_hdr(ses, pSMB);
379 381
380 /* we will send the SMB in two pieces, 382 /* we will send the SMB in three pieces:
381 a fixed length beginning part, and a 383 a fixed length beginning part, an optional
382 second part which will include the strings 384 SPNEGO blob (which can be zero length), and a
383 and rest of bcc area, in order to avoid having 385 last part which will include the strings
384 to do a large buffer 17K allocation */ 386 and rest of bcc area. This allows us to avoid
387 a large buffer 17K allocation */
385 iov[0].iov_base = (char *)pSMB; 388 iov[0].iov_base = (char *)pSMB;
386 iov[0].iov_len = smb_buf->smb_buf_length + 4; 389 iov[0].iov_len = smb_buf->smb_buf_length + 4;
387 390
391 /* setting this here allows the code at the end of the function
392 to free the request buffer if there's an error */
393 resp_buf_type = CIFS_SMALL_BUFFER;
394
388 /* 2000 big enough to fit max user, domain, NOS name etc. */ 395 /* 2000 big enough to fit max user, domain, NOS name etc. */
389 str_area = kmalloc(2000, GFP_KERNEL); 396 str_area = kmalloc(2000, GFP_KERNEL);
390 if (str_area == NULL) { 397 if (str_area == NULL) {
391 cifs_small_buf_release(smb_buf); 398 rc = -ENOMEM;
392 return -ENOMEM; 399 goto ssetup_exit;
393 } 400 }
394 bcc_ptr = str_area; 401 bcc_ptr = str_area;
395 402
396 ses->flags &= ~CIFS_SES_LANMAN; 403 ses->flags &= ~CIFS_SES_LANMAN;
397 404
405 iov[1].iov_base = NULL;
406 iov[1].iov_len = 0;
407
398 if (type == LANMAN) { 408 if (type == LANMAN) {
399#ifdef CONFIG_CIFS_WEAK_PW_HASH 409#ifdef CONFIG_CIFS_WEAK_PW_HASH
400 char lnm_session_key[CIFS_SESS_KEY_SIZE]; 410 char lnm_session_key[CIFS_SESS_KEY_SIZE];
@@ -463,8 +473,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
463 struct ntlmv2_resp */ 473 struct ntlmv2_resp */
464 474
465 if (v2_sess_key == NULL) { 475 if (v2_sess_key == NULL) {
466 cifs_small_buf_release(smb_buf); 476 rc = -ENOMEM;
467 return -ENOMEM; 477 goto ssetup_exit;
468 } 478 }
469 479
470 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 480 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
@@ -499,22 +509,67 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
499 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 509 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
500 } else 510 } else
501 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 511 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
502 } else /* NTLMSSP or SPNEGO */ { 512 } else if (type == Kerberos) {
513#ifdef CONFIG_CIFS_UPCALL
514 struct cifs_spnego_msg *msg;
515 spnego_key = cifs_get_spnego_key(ses);
516 if (IS_ERR(spnego_key)) {
517 rc = PTR_ERR(spnego_key);
518 spnego_key = NULL;
519 goto ssetup_exit;
520 }
521
522 msg = spnego_key->payload.data;
523 /* bail out if key is too long */
524 if (msg->sesskey_len >
525 sizeof(ses->server->mac_signing_key.data.krb5)) {
526 cERROR(1, ("Kerberos signing key too long (%u bytes)",
527 msg->sesskey_len));
528 rc = -EOVERFLOW;
529 goto ssetup_exit;
530 }
531 ses->server->mac_signing_key.len = msg->sesskey_len;
532 memcpy(ses->server->mac_signing_key.data.krb5, msg->data,
533 msg->sesskey_len);
503 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 534 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
504 capabilities |= CAP_EXTENDED_SECURITY; 535 capabilities |= CAP_EXTENDED_SECURITY;
505 pSMB->req.Capabilities = cpu_to_le32(capabilities); 536 pSMB->req.Capabilities = cpu_to_le32(capabilities);
506 /* BB set password lengths */ 537 iov[1].iov_base = msg->data + msg->sesskey_len;
538 iov[1].iov_len = msg->secblob_len;
539 pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
540
541 if (ses->capabilities & CAP_UNICODE) {
542 /* unicode strings must be word aligned */
543 if (iov[0].iov_len % 2) {
544 *bcc_ptr = 0;
545 bcc_ptr++;
546 }
547 unicode_oslm_strings(&bcc_ptr, nls_cp);
548 unicode_domain_string(&bcc_ptr, ses, nls_cp);
549 } else
550 /* BB: is this right? */
551 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
552#else /* ! CONFIG_CIFS_UPCALL */
553 cERROR(1, ("Kerberos negotiated but upcall support disabled!"));
554 rc = -ENOSYS;
555 goto ssetup_exit;
556#endif /* CONFIG_CIFS_UPCALL */
557 } else {
558 cERROR(1, ("secType %d not supported!", type));
559 rc = -ENOSYS;
560 goto ssetup_exit;
507 } 561 }
508 562
509 count = (long) bcc_ptr - (long) str_area; 563 iov[2].iov_base = str_area;
564 iov[2].iov_len = (long) bcc_ptr - (long) str_area;
565
566 count = iov[1].iov_len + iov[2].iov_len;
510 smb_buf->smb_buf_length += count; 567 smb_buf->smb_buf_length += count;
511 568
512 BCC_LE(smb_buf) = cpu_to_le16(count); 569 BCC_LE(smb_buf) = cpu_to_le16(count);
513 570
514 iov[1].iov_base = str_area; 571 rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
515 iov[1].iov_len = count; 572 CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
516 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
517 0 /* not long op */, 1 /* log NT STATUS if any */ );
518 /* SMB request buf freed in SendReceive2 */ 573 /* SMB request buf freed in SendReceive2 */
519 574
520 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); 575 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
@@ -560,6 +615,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
560 ses, nls_cp); 615 ses, nls_cp);
561 616
562ssetup_exit: 617ssetup_exit:
618 if (spnego_key)
619 key_put(spnego_key);
563 kfree(str_area); 620 kfree(str_area);
564 if (resp_buf_type == CIFS_SMALL_BUFFER) { 621 if (resp_buf_type == CIFS_SMALL_BUFFER) {
565 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base)); 622 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 7ed32b3cb781..50b623ad9320 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -308,7 +308,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
308 308
309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) 309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
310{ 310{
311 if (long_op == -1) { 311 if (long_op == CIFS_ASYNC_OP) {
312 /* oplock breaks must not be held up */ 312 /* oplock breaks must not be held up */
313 atomic_inc(&ses->server->inFlight); 313 atomic_inc(&ses->server->inFlight);
314 } else { 314 } else {
@@ -337,7 +337,7 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
337 as they are allowed to block on server */ 337 as they are allowed to block on server */
338 338
339 /* update # of requests on the wire to server */ 339 /* update # of requests on the wire to server */
340 if (long_op < 3) 340 if (long_op != CIFS_BLOCKING_OP)
341 atomic_inc(&ses->server->inFlight); 341 atomic_inc(&ses->server->inFlight);
342 spin_unlock(&GlobalMid_Lock); 342 spin_unlock(&GlobalMid_Lock);
343 break; 343 break;
@@ -415,17 +415,48 @@ static int wait_for_response(struct cifsSesInfo *ses,
415 } 415 }
416} 416}
417 417
418
419/*
420 *
421 * Send an SMB Request. No response info (other than return code)
422 * needs to be parsed.
423 *
424 * flags indicate the type of request buffer and how long to wait
425 * and whether to log NT STATUS code (error) before mapping it to POSIX error
426 *
427 */
428int
429SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
430 struct smb_hdr *in_buf, int flags)
431{
432 int rc;
433 struct kvec iov[1];
434 int resp_buf_type;
435
436 iov[0].iov_base = (char *)in_buf;
437 iov[0].iov_len = in_buf->smb_buf_length + 4;
438 flags |= CIFS_NO_RESP;
439 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
440#ifdef CONFIG_CIFS_DEBUG2
441 cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc));
442#endif
443 return rc;
444}
445
418int 446int
419SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 447SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
420 struct kvec *iov, int n_vec, int *pRespBufType /* ret */, 448 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
421 const int long_op, const int logError) 449 const int flags)
422{ 450{
423 int rc = 0; 451 int rc = 0;
452 int long_op;
424 unsigned int receive_len; 453 unsigned int receive_len;
425 unsigned long timeout; 454 unsigned long timeout;
426 struct mid_q_entry *midQ; 455 struct mid_q_entry *midQ;
427 struct smb_hdr *in_buf = iov[0].iov_base; 456 struct smb_hdr *in_buf = iov[0].iov_base;
428 457
458 long_op = flags & CIFS_TIMEOUT_MASK;
459
429 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 460 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
430 461
431 if ((ses == NULL) || (ses->server == NULL)) { 462 if ((ses == NULL) || (ses->server == NULL)) {
@@ -483,15 +514,22 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
483 if (rc < 0) 514 if (rc < 0)
484 goto out; 515 goto out;
485 516
486 if (long_op == -1) 517 if (long_op == CIFS_STD_OP)
487 goto out; 518 timeout = 15 * HZ;
488 else if (long_op == 2) /* writes past end of file can take loong time */ 519 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
489 timeout = 180 * HZ; 520 timeout = 180 * HZ;
490 else if (long_op == 1) 521 else if (long_op == CIFS_LONG_OP)
491 timeout = 45 * HZ; /* should be greater than 522 timeout = 45 * HZ; /* should be greater than
492 servers oplock break timeout (about 43 seconds) */ 523 servers oplock break timeout (about 43 seconds) */
493 else 524 else if (long_op == CIFS_ASYNC_OP)
494 timeout = 15 * HZ; 525 goto out;
526 else if (long_op == CIFS_BLOCKING_OP)
527 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
528 else {
529 cERROR(1, ("unknown timeout flag %d", long_op));
530 rc = -EIO;
531 goto out;
532 }
495 533
496 /* wait for 15 seconds or until woken up due to response arriving or 534 /* wait for 15 seconds or until woken up due to response arriving or
497 due to last connection to this server being unmounted */ 535 due to last connection to this server being unmounted */
@@ -566,7 +604,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
566 } 604 }
567 605
568 /* BB special case reconnect tid and uid here? */ 606 /* BB special case reconnect tid and uid here? */
569 rc = map_smb_to_linux_error(midQ->resp_buf, logError); 607 rc = map_smb_to_linux_error(midQ->resp_buf,
608 flags & CIFS_LOG_ERROR);
570 609
571 /* convert ByteCount if necessary */ 610 /* convert ByteCount if necessary */
572 if (receive_len >= sizeof(struct smb_hdr) - 4 611 if (receive_len >= sizeof(struct smb_hdr) - 4
@@ -574,8 +613,10 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
574 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 613 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
575 BCC(midQ->resp_buf) = 614 BCC(midQ->resp_buf) =
576 le16_to_cpu(BCC_LE(midQ->resp_buf)); 615 le16_to_cpu(BCC_LE(midQ->resp_buf));
577 midQ->resp_buf = NULL; /* mark it so will not be freed 616 if ((flags & CIFS_NO_RESP) == 0)
578 by DeleteMidQEntry */ 617 midQ->resp_buf = NULL; /* mark it so buf will
618 not be freed by
619 DeleteMidQEntry */
579 } else { 620 } else {
580 rc = -EIO; 621 rc = -EIO;
581 cFYI(1, ("Bad MID state?")); 622 cFYI(1, ("Bad MID state?"));
@@ -663,17 +704,25 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
663 if (rc < 0) 704 if (rc < 0)
664 goto out; 705 goto out;
665 706
666 if (long_op == -1) 707 if (long_op == CIFS_STD_OP)
708 timeout = 15 * HZ;
709 /* wait for 15 seconds or until woken up due to response arriving or
710 due to last connection to this server being unmounted */
711 else if (long_op == CIFS_ASYNC_OP)
667 goto out; 712 goto out;
668 else if (long_op == 2) /* writes past end of file can take loong time */ 713 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
669 timeout = 180 * HZ; 714 timeout = 180 * HZ;
670 else if (long_op == 1) 715 else if (long_op == CIFS_LONG_OP)
671 timeout = 45 * HZ; /* should be greater than 716 timeout = 45 * HZ; /* should be greater than
672 servers oplock break timeout (about 43 seconds) */ 717 servers oplock break timeout (about 43 seconds) */
673 else 718 else if (long_op == CIFS_BLOCKING_OP)
674 timeout = 15 * HZ; 719 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
675 /* wait for 15 seconds or until woken up due to response arriving or 720 else {
676 due to last connection to this server being unmounted */ 721 cERROR(1, ("unknown timeout flag %d", long_op));
722 rc = -EIO;
723 goto out;
724 }
725
677 if (signal_pending(current)) { 726 if (signal_pending(current)) {
678 /* if signal pending do not hold up user for full smb timeout 727 /* if signal pending do not hold up user for full smb timeout
679 but we still give response a chance to complete */ 728 but we still give response a chance to complete */
@@ -812,7 +861,7 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
812 pSMB->hdr.Mid = GetNextMid(ses->server); 861 pSMB->hdr.Mid = GetNextMid(ses->server);
813 862
814 return SendReceive(xid, ses, in_buf, out_buf, 863 return SendReceive(xid, ses, in_buf, out_buf,
815 &bytes_returned, 0); 864 &bytes_returned, CIFS_STD_OP);
816} 865}
817 866
818int 867int
@@ -844,7 +893,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
844 to the same server. We may make this configurable later or 893 to the same server. We may make this configurable later or
845 use ses->maxReq */ 894 use ses->maxReq */
846 895
847 rc = wait_for_free_request(ses, 3); 896 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
848 if (rc) 897 if (rc)
849 return rc; 898 return rc;
850 899
diff --git a/fs/proc/array.c b/fs/proc/array.c
index eba339ecba27..65c62e1bfd6f 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -374,7 +374,9 @@ static cputime_t task_stime(struct task_struct *p)
374 stime = nsec_to_clock_t(p->se.sum_exec_runtime) - 374 stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
375 cputime_to_clock_t(task_utime(p)); 375 cputime_to_clock_t(task_utime(p));
376 376
377 p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime)); 377 if (stime >= 0)
378 p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime));
379
378 return p->prev_stime; 380 return p->prev_stime;
379} 381}
380#endif 382#endif