aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-03 08:30:35 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-03 08:30:35 -0400
commitedc4ff7c08e9885c40e60c4fb39fa42cc91a0602 (patch)
treef375d28043dd4457428a841167dc93d760ba9a46 /fs/cifs
parentcbb9a56177b16294ed347ba7fcb1c66c8adb5dc4 (diff)
parente17df688f7064dae1417ce425dd1e4b71d24d63b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES6
-rw-r--r--fs/cifs/README8
-rw-r--r--fs/cifs/cifsfs.c99
-rw-r--r--fs/cifs/cifssmb.c2
-rw-r--r--fs/cifs/connect.c6
-rw-r--r--fs/cifs/dir.c18
-rw-r--r--fs/cifs/fcntl.c2
-rw-r--r--fs/cifs/file.c34
-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
13 files changed, 140 insertions, 114 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 8a2de038882e..1a27ecb46c9a 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,7 +1,11 @@
1Version 1.42 1Version 1.42
2------------ 2------------
3Fix slow oplock break when mounted to different servers at the same time and 3Fix 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. 4the tids match and we try to find matching fid on wrong server. Fix read
5looping when signing required by server (2.6.16 kernel only). Fix readdir
6vs. rename race which could cause each to hang. Return . and .. even
7if server does not. Allow searches to skip first three entries and
8begin at any location. Fix oops in find_writeable_file.
5 9
6Version 1.41 10Version 1.41
7------------ 11------------
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/cifssmb.c b/fs/cifs/cifssmb.c
index d705500aa283..fd36892eda55 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3119,7 +3119,7 @@ findFirstRetry:
3119 psrch_inf->endOfSearch = FALSE; 3119 psrch_inf->endOfSearch = FALSE;
3120 3120
3121 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 3121 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
3122 psrch_inf->index_of_last_entry = 3122 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
3123 psrch_inf->entries_in_buffer; 3123 psrch_inf->entries_in_buffer;
3124 *pnetfid = parms->SearchHandle; 3124 *pnetfid = parms->SearchHandle;
3125 } else { 3125 } else {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0b86d5ca9014..d2ec806a4f32 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3447,6 +3447,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3447 pSesInfo->server->secMode, 3447 pSesInfo->server->secMode,
3448 pSesInfo->server->capabilities, 3448 pSesInfo->server->capabilities,
3449 pSesInfo->server->timeZone)); 3449 pSesInfo->server->timeZone));
3450#ifdef CONFIG_CIFS_EXPERIMENTAL
3451 if(experimEnabled > 1)
3452 rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */,
3453 &ntlmv2_flag, nls_info);
3454 else
3455#endif
3450 if (extended_security 3456 if (extended_security
3451 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3457 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3452 && (pSesInfo->server->secType == NTLMSSP)) { 3458 && (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..e152bf6afa60 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -203,9 +203,7 @@ int cifs_open(struct inode *inode, struct file *file)
203 } 203 }
204 } 204 }
205 205
206 mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
207 full_path = build_path_from_dentry(file->f_dentry); 206 full_path = build_path_from_dentry(file->f_dentry);
208 mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
209 if (full_path == NULL) { 207 if (full_path == NULL) {
210 FreeXid(xid); 208 FreeXid(xid);
211 return -ENOMEM; 209 return -ENOMEM;
@@ -906,8 +904,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
906 if (rc != 0) 904 if (rc != 0)
907 break; 905 break;
908 } 906 }
909 /* BB FIXME We can not sign across two buffers yet */ 907 if(experimEnabled || (pTcon->ses->server->secMode &
910 if((pTcon->ses->server->secMode &
911 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { 908 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
912 struct kvec iov[2]; 909 struct kvec iov[2];
913 unsigned int len; 910 unsigned int len;
@@ -923,13 +920,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
923 *poffset, &bytes_written, 920 *poffset, &bytes_written,
924 iov, 1, long_op); 921 iov, 1, long_op);
925 } else 922 } else
926 /* BB FIXME fixup indentation of line below */ 923 rc = CIFSSMBWrite(xid, pTcon,
927 rc = CIFSSMBWrite(xid, pTcon, 924 open_file->netfid,
928 open_file->netfid, 925 min_t(const int, cifs_sb->wsize,
929 min_t(const int, cifs_sb->wsize, 926 write_size - total_written),
930 write_size - total_written), 927 *poffset, &bytes_written,
931 *poffset, &bytes_written, 928 write_data + total_written,
932 write_data + total_written, NULL, long_op); 929 NULL, long_op);
933 } 930 }
934 if (rc || (bytes_written == 0)) { 931 if (rc || (bytes_written == 0)) {
935 if (total_written) 932 if (total_written)
@@ -968,6 +965,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
968 struct cifsFileInfo *open_file; 965 struct cifsFileInfo *open_file;
969 int rc; 966 int rc;
970 967
968 /* Having a null inode here (because mapping->host was set to zero by
969 the VFS or MM) should not happen but we had reports of on oops (due to
970 it being zero) during stress testcases so we need to check for it */
971
972 if(cifs_inode == NULL) {
973 cERROR(1,("Null inode passed to cifs_writeable_file"));
974 dump_stack();
975 return NULL;
976 }
977
971 read_lock(&GlobalSMBSeslock); 978 read_lock(&GlobalSMBSeslock);
972 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 979 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
973 if (open_file->closePend) 980 if (open_file->closePend)
@@ -1093,12 +1100,11 @@ static int cifs_writepages(struct address_space *mapping,
1093 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1100 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1094 return generic_writepages(mapping, wbc); 1101 return generic_writepages(mapping, wbc);
1095 1102
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)) 1103 if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1099 if(cifs_sb->tcon->ses->server->secMode & 1104 if(cifs_sb->tcon->ses->server->secMode &
1100 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 1105 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1101 return generic_writepages(mapping, wbc); 1106 if(!experimEnabled)
1107 return generic_writepages(mapping, wbc);
1102 1108
1103 /* 1109 /*
1104 * BB: Is this meaningful for a non-block-device file system? 1110 * 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;