aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index ba4cbe9b0684..66b825ade3e1 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -46,7 +46,8 @@ char *
46build_path_from_dentry(struct dentry *direntry) 46build_path_from_dentry(struct dentry *direntry)
47{ 47{
48 struct dentry *temp; 48 struct dentry *temp;
49 int namelen = 0; 49 int namelen;
50 int pplen;
50 char *full_path; 51 char *full_path;
51 char dirsep; 52 char dirsep;
52 53
@@ -56,7 +57,9 @@ build_path_from_dentry(struct dentry *direntry)
56 when the server crashed */ 57 when the server crashed */
57 58
58 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 59 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
60 pplen = CIFS_SB(direntry->d_sb)->prepathlen;
59cifs_bp_rename_retry: 61cifs_bp_rename_retry:
62 namelen = pplen;
60 for (temp = direntry; !IS_ROOT(temp);) { 63 for (temp = direntry; !IS_ROOT(temp);) {
61 namelen += (1 + temp->d_name.len); 64 namelen += (1 + temp->d_name.len);
62 temp = temp->d_parent; 65 temp = temp->d_parent;
@@ -70,7 +73,6 @@ cifs_bp_rename_retry:
70 if(full_path == NULL) 73 if(full_path == NULL)
71 return full_path; 74 return full_path;
72 full_path[namelen] = 0; /* trailing null */ 75 full_path[namelen] = 0; /* trailing null */
73
74 for (temp = direntry; !IS_ROOT(temp);) { 76 for (temp = direntry; !IS_ROOT(temp);) {
75 namelen -= 1 + temp->d_name.len; 77 namelen -= 1 + temp->d_name.len;
76 if (namelen < 0) { 78 if (namelen < 0) {
@@ -79,7 +81,7 @@ cifs_bp_rename_retry:
79 full_path[namelen] = dirsep; 81 full_path[namelen] = dirsep;
80 strncpy(full_path + namelen + 1, temp->d_name.name, 82 strncpy(full_path + namelen + 1, temp->d_name.name,
81 temp->d_name.len); 83 temp->d_name.len);
82 cFYI(0, (" name: %s ", full_path + namelen)); 84 cFYI(0, ("name: %s", full_path + namelen));
83 } 85 }
84 temp = temp->d_parent; 86 temp = temp->d_parent;
85 if(temp == NULL) { 87 if(temp == NULL) {
@@ -88,18 +90,23 @@ cifs_bp_rename_retry:
88 return NULL; 90 return NULL;
89 } 91 }
90 } 92 }
91 if (namelen != 0) { 93 if (namelen != pplen) {
92 cERROR(1, 94 cERROR(1,
93 ("We did not end path lookup where we expected namelen is %d", 95 ("did not end path lookup where expected namelen is %d",
94 namelen)); 96 namelen));
95 /* presumably this is only possible if we were racing with a rename 97 /* presumably this is only possible if racing with a rename
96 of one of the parent directories (we can not lock the dentries 98 of one of the parent directories (we can not lock the dentries
97 above us to prevent this, but retrying should be harmless) */ 99 above us to prevent this, but retrying should be harmless) */
98 kfree(full_path); 100 kfree(full_path);
99 namelen = 0;
100 goto cifs_bp_rename_retry; 101 goto cifs_bp_rename_retry;
101 } 102 }
102 103 /* DIR_SEP already set for byte 0 / vs \ but not for
104 subsequent slashes in prepath which currently must
105 be entered the right way - not sure if there is an alternative
106 since the '\' is a valid posix character so we can not switch
107 those safely to '/' if any are found in the middle of the prepath */
108 /* BB test paths to Windows with '/' in the midst of prepath */
109 strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen);
103 return full_path; 110 return full_path;
104} 111}
105 112
@@ -267,6 +274,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
267 pCifsFile->invalidHandle = FALSE; 274 pCifsFile->invalidHandle = FALSE;
268 pCifsFile->closePend = FALSE; 275 pCifsFile->closePend = FALSE;
269 init_MUTEX(&pCifsFile->fh_sem); 276 init_MUTEX(&pCifsFile->fh_sem);
277 init_MUTEX(&pCifsFile->lock_sem);
278 INIT_LIST_HEAD(&pCifsFile->llist);
279 atomic_set(&pCifsFile->wrtPending,0);
280
270 /* set the following in open now 281 /* set the following in open now
271 pCifsFile->pfile = file; */ 282 pCifsFile->pfile = file; */
272 write_lock(&GlobalSMBSeslock); 283 write_lock(&GlobalSMBSeslock);