aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-09-21 03:02:52 -0400
committerSteve French <sfrench@us.ibm.com>2006-09-21 03:02:52 -0400
commit2fe87f02a04ad6e7075023a87fe38eb458a4bb9d (patch)
treeec095fecdccad724faa6560cf7a81a9494a5a093 /fs/cifs/dir.c
parentb835bebe95608c81270636a78b70333afb011925 (diff)
[CIFS] Support deep tree mounts (e.g. mounts to //server/share/path)
Samba bugzilla #4040 Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 914239d53634..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