aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES7
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c40
-rw-r--r--fs/cifs/connect.c97
-rw-r--r--fs/cifs/file.c12
6 files changed, 140 insertions, 20 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 1a27ecb46c9a..7271bb0257f6 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,10 @@
1Version 1.43
2------------
3POSIX locking to servers which support CIFS POSIX Extensions
4(disabled by default controlled by proc/fs/cifs/Experimental).
5Handle conversion of long share names (especially Asian languages)
6to Unicode during mount.
7
1Version 1.42 8Version 1.42
2------------ 9------------
3Fix slow oplock break when mounted to different servers at the same time and 10Fix slow oplock break when mounted to different servers at the same time and
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 4e829dc672a6..c98755dca868 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
99extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 99extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
100extern int cifs_ioctl (struct inode * inode, struct file * filep, 100extern int cifs_ioctl (struct inode * inode, struct file * filep,
101 unsigned int command, unsigned long arg); 101 unsigned int command, unsigned long arg);
102#define CIFS_VERSION "1.42" 102#define CIFS_VERSION "1.43"
103#endif /* _CIFSFS_H */ 103#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 2879ba343ca7..310ea2f0e0bf 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -267,7 +267,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
267 const int waitFlag); 267 const int waitFlag);
268extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 268extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
269 const __u16 smb_file_id, const int get_flag, 269 const __u16 smb_file_id, const int get_flag,
270 const __u64 len, const __u64 offset, 270 const __u64 len, struct file_lock *,
271 const __u16 lock_type, const int waitFlag); 271 const __u16 lock_type, const int waitFlag);
272extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 272extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
273extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 273extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index fd36892eda55..925881e00ff2 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1355,7 +1355,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1355int 1355int
1356CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 1356CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1357 const __u16 smb_file_id, const int get_flag, const __u64 len, 1357 const __u16 smb_file_id, const int get_flag, const __u64 len,
1358 const __u64 lkoffset, const __u16 lock_type, const int waitFlag) 1358 struct file_lock *pLockData, const __u16 lock_type,
1359 const int waitFlag)
1359{ 1360{
1360 struct smb_com_transaction2_sfi_req *pSMB = NULL; 1361 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1361 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 1362 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -1366,6 +1367,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1366 __u16 params, param_offset, offset, byte_count, count; 1367 __u16 params, param_offset, offset, byte_count, count;
1367 1368
1368 cFYI(1, ("Posix Lock")); 1369 cFYI(1, ("Posix Lock"));
1370
1371 if(pLockData == NULL)
1372 return EINVAL;
1373
1369 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 1374 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1370 1375
1371 if (rc) 1376 if (rc)
@@ -1404,10 +1409,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1404 1409
1405 parm_data->lock_type = cpu_to_le16(lock_type); 1410 parm_data->lock_type = cpu_to_le16(lock_type);
1406 if(waitFlag) 1411 if(waitFlag)
1407 parm_data->lock_flags = 1; 1412 parm_data->lock_flags = cpu_to_le16(1);
1408 parm_data->pid = cpu_to_le32(current->tgid); 1413 parm_data->pid = cpu_to_le32(current->tgid);
1409 parm_data->start = lkoffset; 1414 parm_data->start = cpu_to_le64(pLockData->fl_start);
1410 parm_data->length = len; /* normalize negative numbers */ 1415 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
1411 1416
1412 pSMB->DataOffset = cpu_to_le16(offset); 1417 pSMB->DataOffset = cpu_to_le16(offset);
1413 pSMB->Fid = smb_file_id; 1418 pSMB->Fid = smb_file_id;
@@ -1419,8 +1424,33 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1419 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1424 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1420 if (rc) { 1425 if (rc) {
1421 cFYI(1, ("Send error in Posix Lock = %d", rc)); 1426 cFYI(1, ("Send error in Posix Lock = %d", rc));
1422 } 1427 } else if (get_flag) {
1428 /* lock structure can be returned on get */
1429 __u16 data_offset;
1430 __u16 data_count;
1431 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1423 1432
1433 if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) {
1434 rc = -EIO; /* bad smb */
1435 goto plk_err_exit;
1436 }
1437 if(pLockData == NULL) {
1438 rc = -EINVAL;
1439 goto plk_err_exit;
1440 }
1441 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
1442 data_count = le16_to_cpu(pSMBr->t2.DataCount);
1443 if(data_count < sizeof(struct cifs_posix_lock)) {
1444 rc = -EIO;
1445 goto plk_err_exit;
1446 }
1447 parm_data = (struct cifs_posix_lock *)
1448 ((char *)&pSMBr->hdr.Protocol + data_offset);
1449 if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
1450 pLockData->fl_type = F_UNLCK;
1451 }
1452
1453plk_err_exit:
1424 if (pSMB) 1454 if (pSMB)
1425 cifs_small_buf_release(pSMB); 1455 cifs_small_buf_release(pSMB);
1426 1456
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d2ec806a4f32..bae1479318d1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2148,6 +2148,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2148/* We look for obvious messed up bcc or strings in response so we do not go off 2148/* We look for obvious messed up bcc or strings in response so we do not go off
2149 the end since (at least) WIN2K and Windows XP have a major bug in not null 2149 the end since (at least) WIN2K and Windows XP have a major bug in not null
2150 terminating last Unicode string in response */ 2150 terminating last Unicode string in response */
2151 if(ses->serverOS)
2152 kfree(ses->serverOS);
2151 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); 2153 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL);
2152 if(ses->serverOS == NULL) 2154 if(ses->serverOS == NULL)
2153 goto sesssetup_nomem; 2155 goto sesssetup_nomem;
@@ -2160,6 +2162,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2160 if (remaining_words > 0) { 2162 if (remaining_words > 0) {
2161 len = UniStrnlen((wchar_t *)bcc_ptr, 2163 len = UniStrnlen((wchar_t *)bcc_ptr,
2162 remaining_words-1); 2164 remaining_words-1);
2165 if(ses->serverNOS)
2166 kfree(ses->serverNOS);
2163 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); 2167 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
2164 if(ses->serverNOS == NULL) 2168 if(ses->serverNOS == NULL)
2165 goto sesssetup_nomem; 2169 goto sesssetup_nomem;
@@ -2177,6 +2181,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2177 if (remaining_words > 0) { 2181 if (remaining_words > 0) {
2178 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2182 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2179 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2183 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2184 if(ses->serverDomain)
2185 kfree(ses->serverDomain);
2180 ses->serverDomain = 2186 ses->serverDomain =
2181 kzalloc(2*(len+1),GFP_KERNEL); 2187 kzalloc(2*(len+1),GFP_KERNEL);
2182 if(ses->serverDomain == NULL) 2188 if(ses->serverDomain == NULL)
@@ -2187,15 +2193,22 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2187 ses->serverDomain[2*len] = 0; 2193 ses->serverDomain[2*len] = 0;
2188 ses->serverDomain[1+(2*len)] = 0; 2194 ses->serverDomain[1+(2*len)] = 0;
2189 } /* else no more room so create dummy domain string */ 2195 } /* else no more room so create dummy domain string */
2190 else 2196 else {
2197 if(ses->serverDomain)
2198 kfree(ses->serverDomain);
2191 ses->serverDomain = 2199 ses->serverDomain =
2192 kzalloc(2, GFP_KERNEL); 2200 kzalloc(2, GFP_KERNEL);
2201 }
2193 } else { /* no room so create dummy domain and NOS string */ 2202 } else { /* no room so create dummy domain and NOS string */
2194 /* if these kcallocs fail not much we 2203 /* if these kcallocs fail not much we
2195 can do, but better to not fail the 2204 can do, but better to not fail the
2196 sesssetup itself */ 2205 sesssetup itself */
2206 if(ses->serverDomain)
2207 kfree(ses->serverDomain);
2197 ses->serverDomain = 2208 ses->serverDomain =
2198 kzalloc(2, GFP_KERNEL); 2209 kzalloc(2, GFP_KERNEL);
2210 if(ses->serverNOS)
2211 kfree(ses->serverNOS);
2199 ses->serverNOS = 2212 ses->serverNOS =
2200 kzalloc(2, GFP_KERNEL); 2213 kzalloc(2, GFP_KERNEL);
2201 } 2214 }
@@ -2204,6 +2217,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2204 if (((long) bcc_ptr + len) - (long) 2217 if (((long) bcc_ptr + len) - (long)
2205 pByteArea(smb_buffer_response) 2218 pByteArea(smb_buffer_response)
2206 <= BCC(smb_buffer_response)) { 2219 <= BCC(smb_buffer_response)) {
2220 if(ses->serverOS)
2221 kfree(ses->serverOS);
2207 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 2222 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
2208 if(ses->serverOS == NULL) 2223 if(ses->serverOS == NULL)
2209 goto sesssetup_nomem; 2224 goto sesssetup_nomem;
@@ -2214,6 +2229,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2214 bcc_ptr++; 2229 bcc_ptr++;
2215 2230
2216 len = strnlen(bcc_ptr, 1024); 2231 len = strnlen(bcc_ptr, 1024);
2232 if(ses->serverNOS)
2233 kfree(ses->serverNOS);
2217 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2234 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2218 if(ses->serverNOS == NULL) 2235 if(ses->serverNOS == NULL)
2219 goto sesssetup_nomem; 2236 goto sesssetup_nomem;
@@ -2223,6 +2240,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2223 bcc_ptr++; 2240 bcc_ptr++;
2224 2241
2225 len = strnlen(bcc_ptr, 1024); 2242 len = strnlen(bcc_ptr, 1024);
2243 if(ses->serverDomain)
2244 kfree(ses->serverDomain);
2226 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL); 2245 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL);
2227 if(ses->serverDomain == NULL) 2246 if(ses->serverDomain == NULL)
2228 goto sesssetup_nomem; 2247 goto sesssetup_nomem;
@@ -2427,6 +2446,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2427/* We look for obvious messed up bcc or strings in response so we do not go off 2446/* We look for obvious messed up bcc or strings in response so we do not go off
2428 the end since (at least) WIN2K and Windows XP have a major bug in not null 2447 the end since (at least) WIN2K and Windows XP have a major bug in not null
2429 terminating last Unicode string in response */ 2448 terminating last Unicode string in response */
2449 if(ses->serverOS)
2450 kfree(ses->serverOS);
2430 ses->serverOS = 2451 ses->serverOS =
2431 kzalloc(2 * (len + 1), GFP_KERNEL); 2452 kzalloc(2 * (len + 1), GFP_KERNEL);
2432 cifs_strfromUCS_le(ses->serverOS, 2453 cifs_strfromUCS_le(ses->serverOS,
@@ -2441,6 +2462,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2441 len = UniStrnlen((wchar_t *)bcc_ptr, 2462 len = UniStrnlen((wchar_t *)bcc_ptr,
2442 remaining_words 2463 remaining_words
2443 - 1); 2464 - 1);
2465 if(ses->serverNOS)
2466 kfree(ses->serverNOS);
2444 ses->serverNOS = 2467 ses->serverNOS =
2445 kzalloc(2 * (len + 1), 2468 kzalloc(2 * (len + 1),
2446 GFP_KERNEL); 2469 GFP_KERNEL);
@@ -2454,7 +2477,9 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2454 remaining_words -= len + 1; 2477 remaining_words -= len + 1;
2455 if (remaining_words > 0) { 2478 if (remaining_words > 0) {
2456 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2479 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2457 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2480 /* last string not null terminated (e.g.Windows XP/2000) */
2481 if(ses->serverDomain)
2482 kfree(ses->serverDomain);
2458 ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); 2483 ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
2459 cifs_strfromUCS_le(ses->serverDomain, 2484 cifs_strfromUCS_le(ses->serverDomain,
2460 (__le16 *)bcc_ptr, 2485 (__le16 *)bcc_ptr,
@@ -2463,11 +2488,18 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2463 ses->serverDomain[2*len] = 0; 2488 ses->serverDomain[2*len] = 0;
2464 ses->serverDomain[1+(2*len)] = 0; 2489 ses->serverDomain[1+(2*len)] = 0;
2465 } /* else no more room so create dummy domain string */ 2490 } /* else no more room so create dummy domain string */
2466 else 2491 else {
2492 if(ses->serverDomain)
2493 kfree(ses->serverDomain);
2467 ses->serverDomain = 2494 ses->serverDomain =
2468 kzalloc(2,GFP_KERNEL); 2495 kzalloc(2,GFP_KERNEL);
2469 } else { /* no room so create dummy domain and NOS string */ 2496 }
2497 } else {/* no room use dummy domain&NOS */
2498 if(ses->serverDomain)
2499 kfree(ses->serverDomain);
2470 ses->serverDomain = kzalloc(2, GFP_KERNEL); 2500 ses->serverDomain = kzalloc(2, GFP_KERNEL);
2501 if(ses->serverNOS)
2502 kfree(ses->serverNOS);
2471 ses->serverNOS = kzalloc(2, GFP_KERNEL); 2503 ses->serverNOS = kzalloc(2, GFP_KERNEL);
2472 } 2504 }
2473 } else { /* ASCII */ 2505 } else { /* ASCII */
@@ -2476,6 +2508,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2476 if (((long) bcc_ptr + len) - (long) 2508 if (((long) bcc_ptr + len) - (long)
2477 pByteArea(smb_buffer_response) 2509 pByteArea(smb_buffer_response)
2478 <= BCC(smb_buffer_response)) { 2510 <= BCC(smb_buffer_response)) {
2511 if(ses->serverOS)
2512 kfree(ses->serverOS);
2479 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 2513 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
2480 strncpy(ses->serverOS, bcc_ptr, len); 2514 strncpy(ses->serverOS, bcc_ptr, len);
2481 2515
@@ -2484,6 +2518,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2484 bcc_ptr++; 2518 bcc_ptr++;
2485 2519
2486 len = strnlen(bcc_ptr, 1024); 2520 len = strnlen(bcc_ptr, 1024);
2521 if(ses->serverNOS)
2522 kfree(ses->serverNOS);
2487 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2523 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2488 strncpy(ses->serverNOS, bcc_ptr, len); 2524 strncpy(ses->serverNOS, bcc_ptr, len);
2489 bcc_ptr += len; 2525 bcc_ptr += len;
@@ -2491,6 +2527,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2491 bcc_ptr++; 2527 bcc_ptr++;
2492 2528
2493 len = strnlen(bcc_ptr, 1024); 2529 len = strnlen(bcc_ptr, 1024);
2530 if(ses->serverDomain)
2531 kfree(ses->serverDomain);
2494 ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); 2532 ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
2495 strncpy(ses->serverDomain, bcc_ptr, len); 2533 strncpy(ses->serverDomain, bcc_ptr, len);
2496 bcc_ptr += len; 2534 bcc_ptr += len;
@@ -2728,6 +2766,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2728/* We look for obvious messed up bcc or strings in response so we do not go off 2766/* We look for obvious messed up bcc or strings in response so we do not go off
2729 the end since (at least) WIN2K and Windows XP have a major bug in not null 2767 the end since (at least) WIN2K and Windows XP have a major bug in not null
2730 terminating last Unicode string in response */ 2768 terminating last Unicode string in response */
2769 if(ses->serverOS)
2770 kfree(ses->serverOS);
2731 ses->serverOS = 2771 ses->serverOS =
2732 kzalloc(2 * (len + 1), GFP_KERNEL); 2772 kzalloc(2 * (len + 1), GFP_KERNEL);
2733 cifs_strfromUCS_le(ses->serverOS, 2773 cifs_strfromUCS_le(ses->serverOS,
@@ -2743,6 +2783,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2743 bcc_ptr, 2783 bcc_ptr,
2744 remaining_words 2784 remaining_words
2745 - 1); 2785 - 1);
2786 if(ses->serverNOS)
2787 kfree(ses->serverNOS);
2746 ses->serverNOS = 2788 ses->serverNOS =
2747 kzalloc(2 * (len + 1), 2789 kzalloc(2 * (len + 1),
2748 GFP_KERNEL); 2790 GFP_KERNEL);
@@ -2760,6 +2802,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2760 if (remaining_words > 0) { 2802 if (remaining_words > 0) {
2761 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2803 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2762 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2804 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2805 if(ses->serverDomain)
2806 kfree(ses->serverDomain);
2763 ses->serverDomain = 2807 ses->serverDomain =
2764 kzalloc(2 * 2808 kzalloc(2 *
2765 (len + 2809 (len +
@@ -2777,13 +2821,20 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2777 [1 + (2 * len)] 2821 [1 + (2 * len)]
2778 = 0; 2822 = 0;
2779 } /* else no more room so create dummy domain string */ 2823 } /* else no more room so create dummy domain string */
2780 else 2824 else {
2825 if(ses->serverDomain)
2826 kfree(ses->serverDomain);
2781 ses->serverDomain = 2827 ses->serverDomain =
2782 kzalloc(2, 2828 kzalloc(2,
2783 GFP_KERNEL); 2829 GFP_KERNEL);
2830 }
2784 } else { /* no room so create dummy domain and NOS string */ 2831 } else { /* no room so create dummy domain and NOS string */
2832 if(ses->serverDomain);
2833 kfree(ses->serverDomain);
2785 ses->serverDomain = 2834 ses->serverDomain =
2786 kzalloc(2, GFP_KERNEL); 2835 kzalloc(2, GFP_KERNEL);
2836 if(ses->serverNOS)
2837 kfree(ses->serverNOS);
2787 ses->serverNOS = 2838 ses->serverNOS =
2788 kzalloc(2, GFP_KERNEL); 2839 kzalloc(2, GFP_KERNEL);
2789 } 2840 }
@@ -2792,6 +2843,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2792 if (((long) bcc_ptr + len) - (long) 2843 if (((long) bcc_ptr + len) - (long)
2793 pByteArea(smb_buffer_response) 2844 pByteArea(smb_buffer_response)
2794 <= BCC(smb_buffer_response)) { 2845 <= BCC(smb_buffer_response)) {
2846 if(ses->serverOS)
2847 kfree(ses->serverOS);
2795 ses->serverOS = 2848 ses->serverOS =
2796 kzalloc(len + 1, 2849 kzalloc(len + 1,
2797 GFP_KERNEL); 2850 GFP_KERNEL);
@@ -2803,6 +2856,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2803 bcc_ptr++; 2856 bcc_ptr++;
2804 2857
2805 len = strnlen(bcc_ptr, 1024); 2858 len = strnlen(bcc_ptr, 1024);
2859 if(ses->serverNOS)
2860 kfree(ses->serverNOS);
2806 ses->serverNOS = 2861 ses->serverNOS =
2807 kzalloc(len + 1, 2862 kzalloc(len + 1,
2808 GFP_KERNEL); 2863 GFP_KERNEL);
@@ -2812,6 +2867,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2812 bcc_ptr++; 2867 bcc_ptr++;
2813 2868
2814 len = strnlen(bcc_ptr, 1024); 2869 len = strnlen(bcc_ptr, 1024);
2870 if(ses->serverDomain)
2871 kfree(ses->serverDomain);
2815 ses->serverDomain = 2872 ses->serverDomain =
2816 kzalloc(len + 1, 2873 kzalloc(len + 1,
2817 GFP_KERNEL); 2874 GFP_KERNEL);
@@ -3116,6 +3173,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3116/* We look for obvious messed up bcc or strings in response so we do not go off 3173/* We look for obvious messed up bcc or strings in response so we do not go off
3117 the end since (at least) WIN2K and Windows XP have a major bug in not null 3174 the end since (at least) WIN2K and Windows XP have a major bug in not null
3118 terminating last Unicode string in response */ 3175 terminating last Unicode string in response */
3176 if(ses->serverOS)
3177 kfree(ses->serverOS);
3119 ses->serverOS = 3178 ses->serverOS =
3120 kzalloc(2 * (len + 1), GFP_KERNEL); 3179 kzalloc(2 * (len + 1), GFP_KERNEL);
3121 cifs_strfromUCS_le(ses->serverOS, 3180 cifs_strfromUCS_le(ses->serverOS,
@@ -3131,6 +3190,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3131 bcc_ptr, 3190 bcc_ptr,
3132 remaining_words 3191 remaining_words
3133 - 1); 3192 - 1);
3193 if(ses->serverNOS)
3194 kfree(ses->serverNOS);
3134 ses->serverNOS = 3195 ses->serverNOS =
3135 kzalloc(2 * (len + 1), 3196 kzalloc(2 * (len + 1),
3136 GFP_KERNEL); 3197 GFP_KERNEL);
@@ -3147,6 +3208,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3147 if (remaining_words > 0) { 3208 if (remaining_words > 0) {
3148 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 3209 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3149 /* last string not always null terminated (e.g. for Windows XP & 2000) */ 3210 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3211 if(ses->serverDomain)
3212 kfree(ses->serverDomain);
3150 ses->serverDomain = 3213 ses->serverDomain =
3151 kzalloc(2 * 3214 kzalloc(2 *
3152 (len + 3215 (len +
@@ -3172,10 +3235,17 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3172 len)] 3235 len)]
3173 = 0; 3236 = 0;
3174 } /* else no more room so create dummy domain string */ 3237 } /* else no more room so create dummy domain string */
3175 else 3238 else {
3239 if(ses->serverDomain)
3240 kfree(ses->serverDomain);
3176 ses->serverDomain = kzalloc(2,GFP_KERNEL); 3241 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3242 }
3177 } else { /* no room so create dummy domain and NOS string */ 3243 } else { /* no room so create dummy domain and NOS string */
3244 if(ses->serverDomain)
3245 kfree(ses->serverDomain);
3178 ses->serverDomain = kzalloc(2, GFP_KERNEL); 3246 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3247 if(ses->serverNOS)
3248 kfree(ses->serverNOS);
3179 ses->serverNOS = kzalloc(2, GFP_KERNEL); 3249 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3180 } 3250 }
3181 } else { /* ASCII */ 3251 } else { /* ASCII */
@@ -3183,6 +3253,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3183 if (((long) bcc_ptr + len) - 3253 if (((long) bcc_ptr + len) -
3184 (long) pByteArea(smb_buffer_response) 3254 (long) pByteArea(smb_buffer_response)
3185 <= BCC(smb_buffer_response)) { 3255 <= BCC(smb_buffer_response)) {
3256 if(ses->serverOS)
3257 kfree(ses->serverOS);
3186 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 3258 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3187 strncpy(ses->serverOS,bcc_ptr, len); 3259 strncpy(ses->serverOS,bcc_ptr, len);
3188 3260
@@ -3191,6 +3263,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3191 bcc_ptr++; 3263 bcc_ptr++;
3192 3264
3193 len = strnlen(bcc_ptr, 1024); 3265 len = strnlen(bcc_ptr, 1024);
3266 if(ses->serverNOS)
3267 kfree(ses->serverNOS);
3194 ses->serverNOS = kzalloc(len+1,GFP_KERNEL); 3268 ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
3195 strncpy(ses->serverNOS, bcc_ptr, len); 3269 strncpy(ses->serverNOS, bcc_ptr, len);
3196 bcc_ptr += len; 3270 bcc_ptr += len;
@@ -3198,6 +3272,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3198 bcc_ptr++; 3272 bcc_ptr++;
3199 3273
3200 len = strnlen(bcc_ptr, 1024); 3274 len = strnlen(bcc_ptr, 1024);
3275 if(ses->serverDomain)
3276 kfree(ses->serverDomain);
3201 ses->serverDomain = kzalloc(len+1,GFP_KERNEL); 3277 ses->serverDomain = kzalloc(len+1,GFP_KERNEL);
3202 strncpy(ses->serverDomain, bcc_ptr, len); 3278 strncpy(ses->serverDomain, bcc_ptr, len);
3203 bcc_ptr += len; 3279 bcc_ptr += len;
@@ -3282,7 +3358,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3282 bcc_ptr++; /* align */ 3358 bcc_ptr++; /* align */
3283 } 3359 }
3284 3360
3285 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3361 if(ses->server->secMode &
3362 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3286 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3363 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3287 3364
3288 if (ses->capabilities & CAP_STATUS32) { 3365 if (ses->capabilities & CAP_STATUS32) {
@@ -3294,8 +3371,10 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3294 if (ses->capabilities & CAP_UNICODE) { 3371 if (ses->capabilities & CAP_UNICODE) {
3295 smb_buffer->Flags2 |= SMBFLG2_UNICODE; 3372 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3296 length = 3373 length =
3297 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage); 3374 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3298 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ 3375 6 /* max utf8 char length in bytes */ *
3376 (/* server len*/ + 256 /* share len */), nls_codepage);
3377 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3299 bcc_ptr += 2; /* skip trailing null */ 3378 bcc_ptr += 2; /* skip trailing null */
3300 } else { /* ASCII */ 3379 } else { /* ASCII */
3301 strcpy(bcc_ptr, tree); 3380 strcpy(bcc_ptr, tree);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e152bf6afa60..e2b4ce1dad66 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -84,6 +84,8 @@ static inline int cifs_get_disposition(unsigned int flags)
84 return FILE_OVERWRITE_IF; 84 return FILE_OVERWRITE_IF;
85 else if ((flags & O_CREAT) == O_CREAT) 85 else if ((flags & O_CREAT) == O_CREAT)
86 return FILE_OPEN_IF; 86 return FILE_OPEN_IF;
87 else if ((flags & O_TRUNC) == O_TRUNC)
88 return FILE_OVERWRITE;
87 else 89 else
88 return FILE_OPEN; 90 return FILE_OPEN;
89} 91}
@@ -656,7 +658,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
656 else 658 else
657 posix_lock_type = CIFS_WRLCK; 659 posix_lock_type = CIFS_WRLCK;
658 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, 660 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
659 length, pfLock->fl_start, 661 length, pfLock,
660 posix_lock_type, wait_flag); 662 posix_lock_type, wait_flag);
661 FreeXid(xid); 663 FreeXid(xid);
662 return rc; 664 return rc;
@@ -704,7 +706,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
704 return -EOPNOTSUPP; 706 return -EOPNOTSUPP;
705 } 707 }
706 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, 708 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
707 length, pfLock->fl_start, 709 length, pfLock,
708 posix_lock_type, wait_flag); 710 posix_lock_type, wait_flag);
709 } else 711 } else
710 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 712 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
@@ -904,8 +906,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
904 if (rc != 0) 906 if (rc != 0)
905 break; 907 break;
906 } 908 }
907 if(experimEnabled || (pTcon->ses->server->secMode & 909 if(experimEnabled || (pTcon->ses->server &&
908 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { 910 ((pTcon->ses->server->secMode &
911 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
912 == 0))) {
909 struct kvec iov[2]; 913 struct kvec iov[2];
910 unsigned int len; 914 unsigned int len;
911 915