aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES13
-rw-r--r--fs/cifs/README8
-rw-r--r--fs/cifs/cifsfs.c99
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c42
-rw-r--r--fs/cifs/connect.c103
-rw-r--r--fs/cifs/dir.c18
-rw-r--r--fs/cifs/fcntl.c2
-rw-r--r--fs/cifs/file.c44
-rw-r--r--fs/cifs/inode.c6
-rw-r--r--fs/cifs/link.c6
-rw-r--r--fs/cifs/ntlmssp.c14
-rw-r--r--fs/cifs/readdir.c45
-rw-r--r--fs/cifs/xattr.c8
15 files changed, 279 insertions, 133 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 8a2de038882e..7271bb0257f6 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,7 +1,18 @@
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
4the tids match and we try to find matching fid on wrong server. 11the tids match and we try to find matching fid on wrong server. Fix read
12looping when signing required by server (2.6.16 kernel only). Fix readdir
13vs. rename race which could cause each to hang. Return . and .. even
14if server does not. Allow searches to skip first three entries and
15begin at any location. Fix oops in find_writeable_file.
5 16
6Version 1.41 17Version 1.41
7------------ 18------------
diff --git a/fs/cifs/README b/fs/cifs/README
index b2b4d0803761..0355003f4f0a 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -511,6 +511,14 @@ LinuxExtensionsEnabled If set to one then the client will attempt to
511 support and want to map the uid and gid fields 511 support and want to map the uid and gid fields
512 to values supplied at mount (rather than the 512 to values supplied at mount (rather than the
513 actual values, then set this to zero. (default 1) 513 actual values, then set this to zero. (default 1)
514Experimental When set to 1 used to enable certain experimental
515 features (currently enables multipage writes
516 when signing is enabled, the multipage write
517 performance enhancement was disabled when
518 signing turned on in case buffer was modified
519 just before it was sent, also this flag will
520 be used to use the new experimental sessionsetup
521 code).
514 522
515These experimental features and tracing can be enabled by changing flags in 523These experimental features and tracing can be enabled by changing flags in
516/proc/fs/cifs (after the cifs module has been installed or built into the 524/proc/fs/cifs (after the cifs module has been installed or built into the
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index d4b713e5affb..c262d8874ce9 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -33,6 +33,7 @@
33#include <linux/vfs.h> 33#include <linux/vfs.h>
34#include <linux/mempool.h> 34#include <linux/mempool.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/kthread.h>
36#include "cifsfs.h" 37#include "cifsfs.h"
37#include "cifspdu.h" 38#include "cifspdu.h"
38#define DECLARE_GLOBALS_HERE 39#define DECLARE_GLOBALS_HERE
@@ -75,9 +76,6 @@ unsigned int cifs_max_pending = CIFS_MAX_REQ;
75module_param(cifs_max_pending, int, 0); 76module_param(cifs_max_pending, int, 0);
76MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); 77MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
77 78
78static DECLARE_COMPLETION(cifs_oplock_exited);
79static DECLARE_COMPLETION(cifs_dnotify_exited);
80
81extern mempool_t *cifs_sm_req_poolp; 79extern mempool_t *cifs_sm_req_poolp;
82extern mempool_t *cifs_req_poolp; 80extern mempool_t *cifs_req_poolp;
83extern mempool_t *cifs_mid_poolp; 81extern mempool_t *cifs_mid_poolp;
@@ -841,10 +839,6 @@ static int cifs_oplock_thread(void * dummyarg)
841 __u16 netfid; 839 __u16 netfid;
842 int rc; 840 int rc;
843 841
844 daemonize("cifsoplockd");
845 allow_signal(SIGTERM);
846
847 oplockThread = current;
848 do { 842 do {
849 if (try_to_freeze()) 843 if (try_to_freeze())
850 continue; 844 continue;
@@ -900,9 +894,9 @@ static int cifs_oplock_thread(void * dummyarg)
900 set_current_state(TASK_INTERRUPTIBLE); 894 set_current_state(TASK_INTERRUPTIBLE);
901 schedule_timeout(1); /* yield in case q were corrupt */ 895 schedule_timeout(1); /* yield in case q were corrupt */
902 } 896 }
903 } while(!signal_pending(current)); 897 } while (!kthread_should_stop());
904 oplockThread = NULL; 898
905 complete_and_exit (&cifs_oplock_exited, 0); 899 return 0;
906} 900}
907 901
908static int cifs_dnotify_thread(void * dummyarg) 902static int cifs_dnotify_thread(void * dummyarg)
@@ -910,10 +904,6 @@ static int cifs_dnotify_thread(void * dummyarg)
910 struct list_head *tmp; 904 struct list_head *tmp;
911 struct cifsSesInfo *ses; 905 struct cifsSesInfo *ses;
912 906
913 daemonize("cifsdnotifyd");
914 allow_signal(SIGTERM);
915
916 dnotifyThread = current;
917 do { 907 do {
918 if(try_to_freeze()) 908 if(try_to_freeze())
919 continue; 909 continue;
@@ -931,8 +921,9 @@ static int cifs_dnotify_thread(void * dummyarg)
931 wake_up_all(&ses->server->response_q); 921 wake_up_all(&ses->server->response_q);
932 } 922 }
933 read_unlock(&GlobalSMBSeslock); 923 read_unlock(&GlobalSMBSeslock);
934 } while(!signal_pending(current)); 924 } while (!kthread_should_stop());
935 complete_and_exit (&cifs_dnotify_exited, 0); 925
926 return 0;
936} 927}
937 928
938static int __init 929static int __init
@@ -982,32 +973,48 @@ init_cifs(void)
982 } 973 }
983 974
984 rc = cifs_init_inodecache(); 975 rc = cifs_init_inodecache();
985 if (!rc) { 976 if (rc)
986 rc = cifs_init_mids(); 977 goto out_clean_proc;
987 if (!rc) { 978
988 rc = cifs_init_request_bufs(); 979 rc = cifs_init_mids();
989 if (!rc) { 980 if (rc)
990 rc = register_filesystem(&cifs_fs_type); 981 goto out_destroy_inodecache;
991 if (!rc) { 982
992 rc = (int)kernel_thread(cifs_oplock_thread, NULL, 983 rc = cifs_init_request_bufs();
993 CLONE_FS | CLONE_FILES | CLONE_VM); 984 if (rc)
994 if(rc > 0) { 985 goto out_destroy_mids;
995 rc = (int)kernel_thread(cifs_dnotify_thread, NULL, 986
996 CLONE_FS | CLONE_FILES | CLONE_VM); 987 rc = register_filesystem(&cifs_fs_type);
997 if(rc > 0) 988 if (rc)
998 return 0; 989 goto out_destroy_request_bufs;
999 else 990
1000 cERROR(1,("error %d create dnotify thread", rc)); 991 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1001 } else { 992 if (IS_ERR(oplockThread)) {
1002 cERROR(1,("error %d create oplock thread",rc)); 993 rc = PTR_ERR(oplockThread);
1003 } 994 cERROR(1,("error %d create oplock thread", rc));
1004 } 995 goto out_unregister_filesystem;
1005 cifs_destroy_request_bufs();
1006 }
1007 cifs_destroy_mids();
1008 }
1009 cifs_destroy_inodecache();
1010 } 996 }
997
998 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
999 if (IS_ERR(dnotifyThread)) {
1000 rc = PTR_ERR(dnotifyThread);
1001 cERROR(1,("error %d create dnotify thread", rc));
1002 goto out_stop_oplock_thread;
1003 }
1004
1005 return 0;
1006
1007 out_stop_oplock_thread:
1008 kthread_stop(oplockThread);
1009 out_unregister_filesystem:
1010 unregister_filesystem(&cifs_fs_type);
1011 out_destroy_request_bufs:
1012 cifs_destroy_request_bufs();
1013 out_destroy_mids:
1014 cifs_destroy_mids();
1015 out_destroy_inodecache:
1016 cifs_destroy_inodecache();
1017 out_clean_proc:
1011#ifdef CONFIG_PROC_FS 1018#ifdef CONFIG_PROC_FS
1012 cifs_proc_clean(); 1019 cifs_proc_clean();
1013#endif 1020#endif
@@ -1025,14 +1032,8 @@ exit_cifs(void)
1025 cifs_destroy_inodecache(); 1032 cifs_destroy_inodecache();
1026 cifs_destroy_mids(); 1033 cifs_destroy_mids();
1027 cifs_destroy_request_bufs(); 1034 cifs_destroy_request_bufs();
1028 if(oplockThread) { 1035 kthread_stop(oplockThread);
1029 send_sig(SIGTERM, oplockThread, 1); 1036 kthread_stop(dnotifyThread);
1030 wait_for_completion(&cifs_oplock_exited);
1031 }
1032 if(dnotifyThread) {
1033 send_sig(SIGTERM, dnotifyThread, 1);
1034 wait_for_completion(&cifs_dnotify_exited);
1035 }
1036} 1037}
1037 1038
1038MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); 1039MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
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 d705500aa283..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
@@ -3119,7 +3149,7 @@ findFirstRetry:
3119 psrch_inf->endOfSearch = FALSE; 3149 psrch_inf->endOfSearch = FALSE;
3120 3150
3121 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 3151 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
3122 psrch_inf->index_of_last_entry = 3152 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
3123 psrch_inf->entries_in_buffer; 3153 psrch_inf->entries_in_buffer;
3124 *pnetfid = parms->SearchHandle; 3154 *pnetfid = parms->SearchHandle;
3125 } else { 3155 } else {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0b86d5ca9014..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);
@@ -3447,6 +3526,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3447 pSesInfo->server->secMode, 3526 pSesInfo->server->secMode,
3448 pSesInfo->server->capabilities, 3527 pSesInfo->server->capabilities,
3449 pSesInfo->server->timeZone)); 3528 pSesInfo->server->timeZone));
3529#ifdef CONFIG_CIFS_EXPERIMENTAL
3530 if(experimEnabled > 1)
3531 rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */,
3532 &ntlmv2_flag, nls_info);
3533 else
3534#endif
3450 if (extended_security 3535 if (extended_security
3451 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3536 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3452 && (pSesInfo->server->secType == NTLMSSP)) { 3537 && (pSesInfo->server->secType == NTLMSSP)) {
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 1d0ca3eaaca5..82315edc77d7 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -139,9 +139,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
139 cifs_sb = CIFS_SB(inode->i_sb); 139 cifs_sb = CIFS_SB(inode->i_sb);
140 pTcon = cifs_sb->tcon; 140 pTcon = cifs_sb->tcon;
141 141
142 mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
143 full_path = build_path_from_dentry(direntry); 142 full_path = build_path_from_dentry(direntry);
144 mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
145 if(full_path == NULL) { 143 if(full_path == NULL) {
146 FreeXid(xid); 144 FreeXid(xid);
147 return -ENOMEM; 145 return -ENOMEM;
@@ -316,9 +314,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
316 cifs_sb = CIFS_SB(inode->i_sb); 314 cifs_sb = CIFS_SB(inode->i_sb);
317 pTcon = cifs_sb->tcon; 315 pTcon = cifs_sb->tcon;
318 316
319 mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
320 full_path = build_path_from_dentry(direntry); 317 full_path = build_path_from_dentry(direntry);
321 mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
322 if(full_path == NULL) 318 if(full_path == NULL)
323 rc = -ENOMEM; 319 rc = -ENOMEM;
324 else if (pTcon->ses->capabilities & CAP_UNIX) { 320 else if (pTcon->ses->capabilities & CAP_UNIX) {
@@ -440,6 +436,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
440 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 436 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
441 pTcon = cifs_sb->tcon; 437 pTcon = cifs_sb->tcon;
442 438
439 /*
440 * Don't allow the separator character in a path component.
441 * The VFS will not allow "/", but "\" is allowed by posix.
442 */
443 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
444 int i;
445 for (i = 0; i < direntry->d_name.len; i++)
446 if (direntry->d_name.name[i] == '\\') {
447 cFYI(1, ("Invalid file name"));
448 FreeXid(xid);
449 return ERR_PTR(-EINVAL);
450 }
451 }
452
443 /* can not grab the rename sem here since it would 453 /* can not grab the rename sem here since it would
444 deadlock in the cases (beginning of sys_rename itself) 454 deadlock in the cases (beginning of sys_rename itself)
445 in which we already have the sb rename sem */ 455 in which we already have the sb rename sem */
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index ec4dfe9bf5ef..633a93811328 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -86,9 +86,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
86 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 86 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
87 pTcon = cifs_sb->tcon; 87 pTcon = cifs_sb->tcon;
88 88
89 mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
90 full_path = build_path_from_dentry(file->f_dentry); 89 full_path = build_path_from_dentry(file->f_dentry);
91 mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
92 90
93 if(full_path == NULL) { 91 if(full_path == NULL) {
94 rc = -ENOMEM; 92 rc = -ENOMEM;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 5c497c529772..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}
@@ -203,9 +205,7 @@ int cifs_open(struct inode *inode, struct file *file)
203 } 205 }
204 } 206 }
205 207
206 mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
207 full_path = build_path_from_dentry(file->f_dentry); 208 full_path = build_path_from_dentry(file->f_dentry);
208 mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
209 if (full_path == NULL) { 209 if (full_path == NULL) {
210 FreeXid(xid); 210 FreeXid(xid);
211 return -ENOMEM; 211 return -ENOMEM;
@@ -658,7 +658,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
658 else 658 else
659 posix_lock_type = CIFS_WRLCK; 659 posix_lock_type = CIFS_WRLCK;
660 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, 660 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
661 length, pfLock->fl_start, 661 length, pfLock,
662 posix_lock_type, wait_flag); 662 posix_lock_type, wait_flag);
663 FreeXid(xid); 663 FreeXid(xid);
664 return rc; 664 return rc;
@@ -706,7 +706,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
706 return -EOPNOTSUPP; 706 return -EOPNOTSUPP;
707 } 707 }
708 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, 708 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
709 length, pfLock->fl_start, 709 length, pfLock,
710 posix_lock_type, wait_flag); 710 posix_lock_type, wait_flag);
711 } else 711 } else
712 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 712 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
@@ -906,9 +906,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
906 if (rc != 0) 906 if (rc != 0)
907 break; 907 break;
908 } 908 }
909 /* BB FIXME We can not sign across two buffers yet */ 909 if(experimEnabled || (pTcon->ses->server &&
910 if((pTcon->ses->server->secMode & 910 ((pTcon->ses->server->secMode &
911 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { 911 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
912 == 0))) {
912 struct kvec iov[2]; 913 struct kvec iov[2];
913 unsigned int len; 914 unsigned int len;
914 915
@@ -923,13 +924,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
923 *poffset, &bytes_written, 924 *poffset, &bytes_written,
924 iov, 1, long_op); 925 iov, 1, long_op);
925 } else 926 } else
926 /* BB FIXME fixup indentation of line below */ 927 rc = CIFSSMBWrite(xid, pTcon,
927 rc = CIFSSMBWrite(xid, pTcon, 928 open_file->netfid,
928 open_file->netfid, 929 min_t(const int, cifs_sb->wsize,
929 min_t(const int, cifs_sb->wsize, 930 write_size - total_written),
930 write_size - total_written), 931 *poffset, &bytes_written,
931 *poffset, &bytes_written, 932 write_data + total_written,
932 write_data + total_written, NULL, long_op); 933 NULL, long_op);
933 } 934 }
934 if (rc || (bytes_written == 0)) { 935 if (rc || (bytes_written == 0)) {
935 if (total_written) 936 if (total_written)
@@ -968,6 +969,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
968 struct cifsFileInfo *open_file; 969 struct cifsFileInfo *open_file;
969 int rc; 970 int rc;
970 971
972 /* Having a null inode here (because mapping->host was set to zero by
973 the VFS or MM) should not happen but we had reports of on oops (due to
974 it being zero) during stress testcases so we need to check for it */
975
976 if(cifs_inode == NULL) {
977 cERROR(1,("Null inode passed to cifs_writeable_file"));
978 dump_stack();
979 return NULL;
980 }
981
971 read_lock(&GlobalSMBSeslock); 982 read_lock(&GlobalSMBSeslock);
972 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 983 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
973 if (open_file->closePend) 984 if (open_file->closePend)
@@ -1093,12 +1104,11 @@ static int cifs_writepages(struct address_space *mapping,
1093 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1104 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1094 return generic_writepages(mapping, wbc); 1105 return generic_writepages(mapping, wbc);
1095 1106
1096 /* BB FIXME we do not have code to sign across multiple buffers yet,
1097 so go to older writepage style write which we can sign if needed */
1098 if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) 1107 if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1099 if(cifs_sb->tcon->ses->server->secMode & 1108 if(cifs_sb->tcon->ses->server->secMode &
1100 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 1109 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1101 return generic_writepages(mapping, wbc); 1110 if(!experimEnabled)
1111 return generic_writepages(mapping, wbc);
1102 1112
1103 /* 1113 /*
1104 * BB: Is this meaningful for a non-block-device file system? 1114 * BB: Is this meaningful for a non-block-device file system?
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 957ddd1571c6..4093764ef461 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -722,9 +722,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
722 cifs_sb = CIFS_SB(inode->i_sb); 722 cifs_sb = CIFS_SB(inode->i_sb);
723 pTcon = cifs_sb->tcon; 723 pTcon = cifs_sb->tcon;
724 724
725 mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
726 full_path = build_path_from_dentry(direntry); 725 full_path = build_path_from_dentry(direntry);
727 mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
728 if (full_path == NULL) { 726 if (full_path == NULL) {
729 FreeXid(xid); 727 FreeXid(xid);
730 return -ENOMEM; 728 return -ENOMEM;
@@ -807,9 +805,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
807 cifs_sb = CIFS_SB(inode->i_sb); 805 cifs_sb = CIFS_SB(inode->i_sb);
808 pTcon = cifs_sb->tcon; 806 pTcon = cifs_sb->tcon;
809 807
810 mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
811 full_path = build_path_from_dentry(direntry); 808 full_path = build_path_from_dentry(direntry);
812 mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
813 if (full_path == NULL) { 809 if (full_path == NULL) {
814 FreeXid(xid); 810 FreeXid(xid);
815 return -ENOMEM; 811 return -ENOMEM;
@@ -1141,9 +1137,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1141 rc = 0; 1137 rc = 0;
1142 } 1138 }
1143 1139
1144 mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
1145 full_path = build_path_from_dentry(direntry); 1140 full_path = build_path_from_dentry(direntry);
1146 mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
1147 if (full_path == NULL) { 1141 if (full_path == NULL) {
1148 FreeXid(xid); 1142 FreeXid(xid);
1149 return -ENOMEM; 1143 return -ENOMEM;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 9562f5bba65c..2ec99f833142 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -48,10 +48,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
48/* No need to check for cross device links since server will do that 48/* No need to check for cross device links since server will do that
49 BB note DFS case in future though (when we may have to check) */ 49 BB note DFS case in future though (when we may have to check) */
50 50
51 mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
52 fromName = build_path_from_dentry(old_file); 51 fromName = build_path_from_dentry(old_file);
53 toName = build_path_from_dentry(direntry); 52 toName = build_path_from_dentry(direntry);
54 mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
55 if((fromName == NULL) || (toName == NULL)) { 53 if((fromName == NULL) || (toName == NULL)) {
56 rc = -ENOMEM; 54 rc = -ENOMEM;
57 goto cifs_hl_exit; 55 goto cifs_hl_exit;
@@ -103,9 +101,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
103 101
104 xid = GetXid(); 102 xid = GetXid();
105 103
106 mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
107 full_path = build_path_from_dentry(direntry); 104 full_path = build_path_from_dentry(direntry);
108 mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
109 105
110 if (!full_path) 106 if (!full_path)
111 goto out_no_free; 107 goto out_no_free;
@@ -164,9 +160,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
164 cifs_sb = CIFS_SB(inode->i_sb); 160 cifs_sb = CIFS_SB(inode->i_sb);
165 pTcon = cifs_sb->tcon; 161 pTcon = cifs_sb->tcon;
166 162
167 mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
168 full_path = build_path_from_dentry(direntry); 163 full_path = build_path_from_dentry(direntry);
169 mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
170 164
171 if(full_path == NULL) { 165 if(full_path == NULL) {
172 FreeXid(xid); 166 FreeXid(xid);
diff --git a/fs/cifs/ntlmssp.c b/fs/cifs/ntlmssp.c
index 78866f925747..115359cc7a32 100644
--- a/fs/cifs/ntlmssp.c
+++ b/fs/cifs/ntlmssp.c
@@ -121,6 +121,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
121 } 121 }
122 122
123 123
124 /* copy session key */
125
126 /* if Unicode, align strings to two byte boundary */
127
128 /* copy user name */ /* BB Do we need to special case null user name? */
129
130 /* copy domain name */
131
132 /* copy Linux version */
133
134 /* copy network operating system name */
135
136 /* update bcc and smb buffer length */
137
124/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */ 138/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
125 /* SMB request buf freed in SendReceive2 */ 139 /* SMB request buf freed in SendReceive2 */
126 140
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 2f6e2825571e..b689c5035124 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -404,9 +404,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
404 if(pTcon == NULL) 404 if(pTcon == NULL)
405 return -EINVAL; 405 return -EINVAL;
406 406
407 mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
408 full_path = build_path_from_dentry(file->f_dentry); 407 full_path = build_path_from_dentry(file->f_dentry);
409 mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
410 408
411 if(full_path == NULL) { 409 if(full_path == NULL) {
412 return -ENOMEM; 410 return -ENOMEM;
@@ -592,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
592 first_entry_in_buffer = 590 first_entry_in_buffer =
593 cifsFile->srch_inf.index_of_last_entry - 591 cifsFile->srch_inf.index_of_last_entry -
594 cifsFile->srch_inf.entries_in_buffer; 592 cifsFile->srch_inf.entries_in_buffer;
593
594 /* if first entry in buf is zero then is first buffer
595 in search response data which means it is likely . and ..
596 will be in this buffer, although some servers do not return
597 . and .. for the root of a drive and for those we need
598 to start two entries earlier */
599
595/* dump_cifs_file_struct(file, "In fce ");*/ 600/* dump_cifs_file_struct(file, "In fce ");*/
596 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 601 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
597 is_dir_changed(file)) || 602 is_dir_changed(file)) ||
@@ -634,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
634 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 639 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
635 smbCalcSize((struct smb_hdr *) 640 smbCalcSize((struct smb_hdr *)
636 cifsFile->srch_inf.ntwrk_buf_start); 641 cifsFile->srch_inf.ntwrk_buf_start);
642
643 current_entry = cifsFile->srch_inf.srch_entries_start;
637 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 644 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
638 - cifsFile->srch_inf.entries_in_buffer; 645 - cifsFile->srch_inf.entries_in_buffer;
639 pos_in_buf = index_to_find - first_entry_in_buffer; 646 pos_in_buf = index_to_find - first_entry_in_buffer;
640 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 647 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
641 current_entry = cifsFile->srch_inf.srch_entries_start;
642 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 648 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
643 /* go entry by entry figuring out which is first */ 649 /* go entry by entry figuring out which is first */
644 /* if( . or ..)
645 skip */
646 rc = cifs_entry_is_dot(current_entry,cifsFile);
647 if(rc == 1) /* is . or .. so skip */ {
648 cFYI(1,("Entry is .")); /* BB removeme BB */
649 /* continue; */
650 } else if (rc == 2 ) {
651 cFYI(1,("Entry is ..")); /* BB removeme BB */
652 /* continue; */
653 }
654 current_entry = nxt_dir_entry(current_entry,end_of_smb); 650 current_entry = nxt_dir_entry(current_entry,end_of_smb);
655 } 651 }
656 if((current_entry == NULL) && (i < pos_in_buf)) { 652 if((current_entry == NULL) && (i < pos_in_buf)) {
@@ -770,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
770 if(file->f_dentry == NULL) 766 if(file->f_dentry == NULL)
771 return -ENOENT; 767 return -ENOENT;
772 768
769 rc = cifs_entry_is_dot(pfindEntry,pCifsF);
770 /* skip . and .. since we added them first */
771 if(rc != 0)
772 return 0;
773
773 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 774 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
774 775
775 qstring.name = scratch_buf; 776 qstring.name = scratch_buf;
@@ -898,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
898 899
899 switch ((int) file->f_pos) { 900 switch ((int) file->f_pos) {
900 case 0: 901 case 0:
901 /*if (filldir(direntry, ".", 1, file->f_pos, 902 if (filldir(direntry, ".", 1, file->f_pos,
902 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { 903 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
903 cERROR(1, ("Filldir for current dir failed ")); 904 cERROR(1, ("Filldir for current dir failed"));
904 rc = -ENOMEM; 905 rc = -ENOMEM;
905 break; 906 break;
906 } 907 }
907 file->f_pos++; */ 908 file->f_pos++;
908 case 1: 909 case 1:
909 /* if (filldir(direntry, "..", 2, file->f_pos, 910 if (filldir(direntry, "..", 2, file->f_pos,
910 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { 911 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
911 cERROR(1, ("Filldir for parent dir failed ")); 912 cERROR(1, ("Filldir for parent dir failed "));
912 rc = -ENOMEM; 913 rc = -ENOMEM;
913 break; 914 break;
914 } 915 }
915 file->f_pos++; */ 916 file->f_pos++;
916 case 2: 917 default:
917 /* 1) If search is active, 918 /* 1) If search is active,
918 is in current search buffer? 919 is in current search buffer?
919 if it before then restart search 920 if it before then restart search
@@ -927,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
927 return rc; 928 return rc;
928 } 929 }
929 } 930 }
930 default:
931 if(file->private_data == NULL) { 931 if(file->private_data == NULL) {
932 rc = -EINVAL; 932 rc = -EINVAL;
933 FreeXid(xid); 933 FreeXid(xid);
@@ -947,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
947 kfree(cifsFile->search_resume_name); 947 kfree(cifsFile->search_resume_name);
948 cifsFile->search_resume_name = NULL; */ 948 cifsFile->search_resume_name = NULL; */
949 949
950 /* BB account for . and .. in f_pos as special case */
951
952 rc = find_cifs_entry(xid,pTcon, file, 950 rc = find_cifs_entry(xid,pTcon, file,
953 &current_entry,&num_to_fill); 951 &current_entry,&num_to_fill);
954 if(rc) { 952 if(rc) {
@@ -977,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
977 num_to_fill, i)); 975 num_to_fill, i));
978 break; 976 break;
979 } 977 }
980 978 /* if buggy server returns . and .. late do
979 we want to check for that here? */
981 rc = cifs_filldir(current_entry, file, 980 rc = cifs_filldir(current_entry, file,
982 filldir, direntry,tmp_buf); 981 filldir, direntry,tmp_buf);
983 file->f_pos++; 982 file->f_pos++;
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 3938444d87b2..7754d641775e 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -62,9 +62,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
62 cifs_sb = CIFS_SB(sb); 62 cifs_sb = CIFS_SB(sb);
63 pTcon = cifs_sb->tcon; 63 pTcon = cifs_sb->tcon;
64 64
65 mutex_lock(&sb->s_vfs_rename_mutex);
66 full_path = build_path_from_dentry(direntry); 65 full_path = build_path_from_dentry(direntry);
67 mutex_unlock(&sb->s_vfs_rename_mutex);
68 if(full_path == NULL) { 66 if(full_path == NULL) {
69 FreeXid(xid); 67 FreeXid(xid);
70 return -ENOMEM; 68 return -ENOMEM;
@@ -116,9 +114,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
116 cifs_sb = CIFS_SB(sb); 114 cifs_sb = CIFS_SB(sb);
117 pTcon = cifs_sb->tcon; 115 pTcon = cifs_sb->tcon;
118 116
119 mutex_lock(&sb->s_vfs_rename_mutex);
120 full_path = build_path_from_dentry(direntry); 117 full_path = build_path_from_dentry(direntry);
121 mutex_unlock(&sb->s_vfs_rename_mutex);
122 if(full_path == NULL) { 118 if(full_path == NULL) {
123 FreeXid(xid); 119 FreeXid(xid);
124 return -ENOMEM; 120 return -ENOMEM;
@@ -223,9 +219,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
223 cifs_sb = CIFS_SB(sb); 219 cifs_sb = CIFS_SB(sb);
224 pTcon = cifs_sb->tcon; 220 pTcon = cifs_sb->tcon;
225 221
226 mutex_lock(&sb->s_vfs_rename_mutex);
227 full_path = build_path_from_dentry(direntry); 222 full_path = build_path_from_dentry(direntry);
228 mutex_unlock(&sb->s_vfs_rename_mutex);
229 if(full_path == NULL) { 223 if(full_path == NULL) {
230 FreeXid(xid); 224 FreeXid(xid);
231 return -ENOMEM; 225 return -ENOMEM;
@@ -341,9 +335,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
341 cifs_sb = CIFS_SB(sb); 335 cifs_sb = CIFS_SB(sb);
342 pTcon = cifs_sb->tcon; 336 pTcon = cifs_sb->tcon;
343 337
344 mutex_lock(&sb->s_vfs_rename_mutex);
345 full_path = build_path_from_dentry(direntry); 338 full_path = build_path_from_dentry(direntry);
346 mutex_unlock(&sb->s_vfs_rename_mutex);
347 if(full_path == NULL) { 339 if(full_path == NULL) {
348 FreeXid(xid); 340 FreeXid(xid);
349 return -ENOMEM; 341 return -ENOMEM;