diff options
author | Steve French <sfrench@us.ibm.com> | 2006-09-21 03:02:52 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-09-21 03:02:52 -0400 |
commit | 2fe87f02a04ad6e7075023a87fe38eb458a4bb9d (patch) | |
tree | ec095fecdccad724faa6560cf7a81a9494a5a093 /fs/cifs/dir.c | |
parent | b835bebe95608c81270636a78b70333afb011925 (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.c | 23 |
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 * | |||
46 | build_path_from_dentry(struct dentry *direntry) | 46 | build_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; | ||
59 | cifs_bp_rename_retry: | 61 | cifs_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 | ||