diff options
-rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 36 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 3 |
2 files changed, 19 insertions, 20 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 85c0a74d034d..5fdbf8a14472 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
@@ -104,9 +104,9 @@ static char *cifs_get_share_name(const char *node_name) | |||
104 | 104 | ||
105 | 105 | ||
106 | /** | 106 | /** |
107 | * compose_mount_options - creates mount options for refferral | 107 | * cifs_compose_mount_options - creates mount options for refferral |
108 | * @sb_mountdata: parent/root DFS mount options (template) | 108 | * @sb_mountdata: parent/root DFS mount options (template) |
109 | * @dentry: point where we are going to mount | 109 | * @fullpath: full path in UNC format |
110 | * @ref: server's referral | 110 | * @ref: server's referral |
111 | * @devname: pointer for saving device name | 111 | * @devname: pointer for saving device name |
112 | * | 112 | * |
@@ -116,8 +116,8 @@ static char *cifs_get_share_name(const char *node_name) | |||
116 | * Returns: pointer to new mount options or ERR_PTR. | 116 | * Returns: pointer to new mount options or ERR_PTR. |
117 | * Caller is responcible for freeing retunrned value if it is not error. | 117 | * Caller is responcible for freeing retunrned value if it is not error. |
118 | */ | 118 | */ |
119 | static char *compose_mount_options(const char *sb_mountdata, | 119 | char *cifs_compose_mount_options(const char *sb_mountdata, |
120 | struct dentry *dentry, | 120 | const char *fullpath, |
121 | const struct dfs_info3_param *ref, | 121 | const struct dfs_info3_param *ref, |
122 | char **devname) | 122 | char **devname) |
123 | { | 123 | { |
@@ -128,7 +128,6 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
128 | char *srvIP = NULL; | 128 | char *srvIP = NULL; |
129 | char sep = ','; | 129 | char sep = ','; |
130 | int off, noff; | 130 | int off, noff; |
131 | char *fullpath; | ||
132 | 131 | ||
133 | if (sb_mountdata == NULL) | 132 | if (sb_mountdata == NULL) |
134 | return ERR_PTR(-EINVAL); | 133 | return ERR_PTR(-EINVAL); |
@@ -202,17 +201,6 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
202 | goto compose_mount_options_err; | 201 | goto compose_mount_options_err; |
203 | } | 202 | } |
204 | 203 | ||
205 | /* | ||
206 | * this function gives us a path with a double backslash prefix. We | ||
207 | * require a single backslash for DFS. Temporarily increment fullpath | ||
208 | * to put it in the proper form and decrement before freeing it. | ||
209 | */ | ||
210 | fullpath = build_path_from_dentry(dentry); | ||
211 | if (!fullpath) { | ||
212 | rc = -ENOMEM; | ||
213 | goto compose_mount_options_err; | ||
214 | } | ||
215 | ++fullpath; | ||
216 | tkn_e = strchr(tkn_e + 1, '\\'); | 204 | tkn_e = strchr(tkn_e + 1, '\\'); |
217 | if (tkn_e || (strlen(fullpath) - ref->path_consumed)) { | 205 | if (tkn_e || (strlen(fullpath) - ref->path_consumed)) { |
218 | strncat(mountdata, &sep, 1); | 206 | strncat(mountdata, &sep, 1); |
@@ -221,8 +209,6 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
221 | strcat(mountdata, tkn_e + 1); | 209 | strcat(mountdata, tkn_e + 1); |
222 | strcat(mountdata, fullpath + ref->path_consumed); | 210 | strcat(mountdata, fullpath + ref->path_consumed); |
223 | } | 211 | } |
224 | --fullpath; | ||
225 | kfree(fullpath); | ||
226 | 212 | ||
227 | /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ | 213 | /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ |
228 | /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/ | 214 | /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/ |
@@ -245,10 +231,20 @@ static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent, | |||
245 | struct vfsmount *mnt; | 231 | struct vfsmount *mnt; |
246 | char *mountdata; | 232 | char *mountdata; |
247 | char *devname = NULL; | 233 | char *devname = NULL; |
234 | char *fullpath; | ||
248 | 235 | ||
249 | cifs_sb = CIFS_SB(dentry->d_inode->i_sb); | 236 | cifs_sb = CIFS_SB(dentry->d_inode->i_sb); |
250 | mountdata = compose_mount_options(cifs_sb->mountdata, | 237 | /* |
251 | dentry, ref, &devname); | 238 | * this function gives us a path with a double backslash prefix. We |
239 | * require a single backslash for DFS. | ||
240 | */ | ||
241 | fullpath = build_path_from_dentry(dentry); | ||
242 | if (!fullpath) | ||
243 | return ERR_PTR(-ENOMEM); | ||
244 | |||
245 | mountdata = cifs_compose_mount_options(cifs_sb->mountdata, | ||
246 | fullpath + 1, ref, &devname); | ||
247 | kfree(fullpath); | ||
252 | 248 | ||
253 | if (IS_ERR(mountdata)) | 249 | if (IS_ERR(mountdata)) |
254 | return (struct vfsmount *)mountdata; | 250 | return (struct vfsmount *)mountdata; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index a069e7bfd2d0..4167716d32f2 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -44,6 +44,9 @@ extern void _FreeXid(unsigned int); | |||
44 | extern char *build_path_from_dentry(struct dentry *); | 44 | extern char *build_path_from_dentry(struct dentry *); |
45 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); | 45 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); |
46 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 46 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
47 | extern char *cifs_compose_mount_options(const char *sb_mountdata, | ||
48 | const char *fullpath, const struct dfs_info3_param *ref, | ||
49 | char **devname); | ||
47 | /* extern void renew_parental_timestamps(struct dentry *direntry);*/ | 50 | /* extern void renew_parental_timestamps(struct dentry *direntry);*/ |
48 | extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, | 51 | extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, |
49 | struct smb_hdr * /* input */ , | 52 | struct smb_hdr * /* input */ , |