diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/CHANGES | 13 | ||||
-rw-r--r-- | fs/cifs/README | 8 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 99 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 42 | ||||
-rw-r--r-- | fs/cifs/connect.c | 103 | ||||
-rw-r--r-- | fs/cifs/dir.c | 18 | ||||
-rw-r--r-- | fs/cifs/fcntl.c | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 44 | ||||
-rw-r--r-- | fs/cifs/inode.c | 6 | ||||
-rw-r--r-- | fs/cifs/link.c | 6 | ||||
-rw-r--r-- | fs/cifs/ntlmssp.c | 14 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 45 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 8 |
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 @@ | |||
1 | Version 1.43 | ||
2 | ------------ | ||
3 | POSIX locking to servers which support CIFS POSIX Extensions | ||
4 | (disabled by default controlled by proc/fs/cifs/Experimental). | ||
5 | Handle conversion of long share names (especially Asian languages) | ||
6 | to Unicode during mount. | ||
7 | |||
1 | Version 1.42 | 8 | Version 1.42 |
2 | ------------ | 9 | ------------ |
3 | Fix slow oplock break when mounted to different servers at the same time and | 10 | Fix slow oplock break when mounted to different servers at the same time and |
4 | the tids match and we try to find matching fid on wrong server. | 11 | the tids match and we try to find matching fid on wrong server. Fix read |
12 | looping when signing required by server (2.6.16 kernel only). Fix readdir | ||
13 | vs. rename race which could cause each to hang. Return . and .. even | ||
14 | if server does not. Allow searches to skip first three entries and | ||
15 | begin at any location. Fix oops in find_writeable_file. | ||
5 | 16 | ||
6 | Version 1.41 | 17 | Version 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) |
514 | Experimental 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 | ||
515 | These experimental features and tracing can be enabled by changing flags in | 523 | These 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; | |||
75 | module_param(cifs_max_pending, int, 0); | 76 | module_param(cifs_max_pending, int, 0); |
76 | MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); | 77 | MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); |
77 | 78 | ||
78 | static DECLARE_COMPLETION(cifs_oplock_exited); | ||
79 | static DECLARE_COMPLETION(cifs_dnotify_exited); | ||
80 | |||
81 | extern mempool_t *cifs_sm_req_poolp; | 79 | extern mempool_t *cifs_sm_req_poolp; |
82 | extern mempool_t *cifs_req_poolp; | 80 | extern mempool_t *cifs_req_poolp; |
83 | extern mempool_t *cifs_mid_poolp; | 81 | extern 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 | ||
908 | static int cifs_dnotify_thread(void * dummyarg) | 902 | static 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 | ||
938 | static int __init | 929 | static 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 | ||
1038 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); | 1039 | MODULE_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); | |||
99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 100 | extern 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); |
268 | extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | 268 | extern 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); |
272 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); | 272 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); |
273 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); | 273 | extern 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, | |||
1355 | int | 1355 | int |
1356 | CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | 1356 | CIFSSMBPosixLock(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 | |||
1453 | plk_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 | ¤t_entry,&num_to_fill); | 951 | ¤t_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; |