aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorIgor Mammedov <niallain@gmail.com>2008-10-23 05:58:42 -0400
committerSteve French <sfrench@us.ibm.com>2008-11-17 23:29:06 -0500
commit2c55608f28444c3f33b10312881384c470ceed56 (patch)
tree84064756aee9e936cd5f3eb8f63fe83f04d30de2 /fs/cifs/cifssmb.c
parentab3f992983062440b4f37c666dac66d987902d91 (diff)
Fixed parsing of mount options when doing DFS submount
Since these hit the same routines, and are relatively small, it is easier to review them as one patch. Fixed incorrect handling of the last option in some cases Fixed prefixpath handling convert path_consumed into host depended string length (in bytes) Use non default separator if it is provided in the original mount options Acked-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Igor Mammedov <niallain@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index e6bb2d9d5b09..bdda46dd435a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3899,6 +3899,27 @@ GetInodeNumOut:
3899 return rc; 3899 return rc;
3900} 3900}
3901 3901
3902/* computes length of UCS string converted to host codepage
3903 * @src: UCS string
3904 * @maxlen: length of the input string in UCS characters
3905 * (not in bytes)
3906 *
3907 * return: size of input string in host codepage
3908 */
3909static int hostlen_fromUCS(const __le16 *src, const int maxlen,
3910 const struct nls_table *nls_codepage) {
3911 int i;
3912 int hostlen = 0;
3913 char to[4];
3914 int charlen;
3915 for (i = 0; (i < maxlen) && src[i]; ++i) {
3916 charlen = nls_codepage->uni2char(le16_to_cpu(src[i]),
3917 to, NLS_MAX_CHARSET_SIZE);
3918 hostlen += charlen > 0 ? charlen : 1;
3919 }
3920 return hostlen;
3921}
3922
3902/* parses DFS refferal V3 structure 3923/* parses DFS refferal V3 structure
3903 * caller is responsible for freeing target_nodes 3924 * caller is responsible for freeing target_nodes
3904 * returns: 3925 * returns:
@@ -3909,7 +3930,8 @@ static int
3909parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, 3930parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
3910 unsigned int *num_of_nodes, 3931 unsigned int *num_of_nodes,
3911 struct dfs_info3_param **target_nodes, 3932 struct dfs_info3_param **target_nodes,
3912 const struct nls_table *nls_codepage) 3933 const struct nls_table *nls_codepage, int remap,
3934 const char *searchName)
3913{ 3935{
3914 int i, rc = 0; 3936 int i, rc = 0;
3915 char *data_end; 3937 char *data_end;
@@ -3960,7 +3982,17 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
3960 struct dfs_info3_param *node = (*target_nodes)+i; 3982 struct dfs_info3_param *node = (*target_nodes)+i;
3961 3983
3962 node->flags = le16_to_cpu(pSMBr->DFSFlags); 3984 node->flags = le16_to_cpu(pSMBr->DFSFlags);
3963 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed); 3985 if (is_unicode) {
3986 __le16 *tmp = kmalloc(strlen(searchName)*2, GFP_KERNEL);
3987 cifsConvertToUCS((__le16 *) tmp, searchName,
3988 PATH_MAX, nls_codepage, remap);
3989 node->path_consumed = hostlen_fromUCS(tmp,
3990 le16_to_cpu(pSMBr->PathConsumed)/2,
3991 nls_codepage);
3992 kfree(tmp);
3993 } else
3994 node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
3995
3964 node->server_type = le16_to_cpu(ref->ServerType); 3996 node->server_type = le16_to_cpu(ref->ServerType);
3965 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags); 3997 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
3966 3998
@@ -4093,7 +4125,8 @@ getDFSRetry:
4093 4125
4094 /* parse returned result into more usable form */ 4126 /* parse returned result into more usable form */
4095 rc = parse_DFS_referrals(pSMBr, num_of_nodes, 4127 rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4096 target_nodes, nls_codepage); 4128 target_nodes, nls_codepage, remap,
4129 searchName);
4097 4130
4098GetDFSRefExit: 4131GetDFSRefExit:
4099 cifs_buf_release(pSMB); 4132 cifs_buf_release(pSMB);