aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
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);