summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2014-09-25 15:01:34 -0400
committerSteve French <smfrench@gmail.com>2014-10-16 16:20:20 -0400
commita4153cb1d3cb7d7c16968b0a9cf7c8aacf31424e (patch)
tree161e3d9ab776a5dcc6755f56defad51165bac28c /fs
parentb693855fe67314d501aae74b9adff8788eb2fd82 (diff)
Allow conversion of characters in Mac remap range (part 2)
The previous patch allowed remapping reserved characters from directory listenings, this patch adds conversion the other direction, allowing opening of files with any of the seven reserved characters. Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifs_unicode.c97
-rw-r--r--fs/cifs/smb2misc.c12
2 files changed, 83 insertions, 26 deletions
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index a479cc552617..0aa2c5c2cfe2 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -319,6 +319,66 @@ cifs_strndup_from_utf16(const char *src, const int maxlen,
319 return dst; 319 return dst;
320} 320}
321 321
322static __le16 convert_to_sfu_char(char src_char)
323{
324 __le16 dest_char;
325
326 switch (src_char) {
327 case ':':
328 dest_char = cpu_to_le16(UNI_COLON);
329 break;
330 case '*':
331 dest_char = cpu_to_le16(UNI_ASTERISK);
332 break;
333 case '?':
334 dest_char = cpu_to_le16(UNI_QUESTION);
335 break;
336 case '<':
337 dest_char = cpu_to_le16(UNI_LESSTHAN);
338 break;
339 case '>':
340 dest_char = cpu_to_le16(UNI_GRTRTHAN);
341 break;
342 case '|':
343 dest_char = cpu_to_le16(UNI_PIPE);
344 break;
345 default:
346 dest_char = 0;
347 }
348
349 return dest_char;
350}
351
352static __le16 convert_to_sfm_char(char src_char)
353{
354 __le16 dest_char;
355
356 switch (src_char) {
357 case ':':
358 dest_char = cpu_to_le16(SFM_COLON);
359 break;
360 case '*':
361 dest_char = cpu_to_le16(SFM_ASTERISK);
362 break;
363 case '?':
364 dest_char = cpu_to_le16(SFM_QUESTION);
365 break;
366 case '<':
367 dest_char = cpu_to_le16(SFM_LESSTHAN);
368 break;
369 case '>':
370 dest_char = cpu_to_le16(SFM_GRTRTHAN);
371 break;
372 case '|':
373 dest_char = cpu_to_le16(SFM_PIPE);
374 break;
375 default:
376 dest_char = 0;
377 }
378
379 return dest_char;
380}
381
322/* 382/*
323 * Convert 16 bit Unicode pathname to wire format from string in current code 383 * Convert 16 bit Unicode pathname to wire format from string in current code
324 * page. Conversion may involve remapping up the six characters that are 384 * page. Conversion may involve remapping up the six characters that are
@@ -327,7 +387,7 @@ cifs_strndup_from_utf16(const char *src, const int maxlen,
327 */ 387 */
328int 388int
329cifsConvertToUTF16(__le16 *target, const char *source, int srclen, 389cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
330 const struct nls_table *cp, int mapChars) 390 const struct nls_table *cp, int map_chars)
331{ 391{
332 int i, charlen; 392 int i, charlen;
333 int j = 0; 393 int j = 0;
@@ -335,39 +395,30 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
335 __le16 dst_char; 395 __le16 dst_char;
336 wchar_t tmp; 396 wchar_t tmp;
337 397
338 if (!mapChars) 398 if (map_chars == NO_MAP_UNI_RSVD)
339 return cifs_strtoUTF16(target, source, PATH_MAX, cp); 399 return cifs_strtoUTF16(target, source, PATH_MAX, cp);
340 400
341 for (i = 0; i < srclen; j++) { 401 for (i = 0; i < srclen; j++) {
342 src_char = source[i]; 402 src_char = source[i];
343 charlen = 1; 403 charlen = 1;
344 switch (src_char) { 404
345 case 0: 405 /* check if end of string */
406 if (src_char == 0)
346 goto ctoUTF16_out; 407 goto ctoUTF16_out;
347 case ':': 408
348 dst_char = cpu_to_le16(UNI_COLON); 409 /* see if we must remap this char */
349 break; 410 if (map_chars == SFU_MAP_UNI_RSVD)
350 case '*': 411 dst_char = convert_to_sfu_char(src_char);
351 dst_char = cpu_to_le16(UNI_ASTERISK); 412 else if (map_chars == SFM_MAP_UNI_RSVD)
352 break; 413 dst_char = convert_to_sfm_char(src_char);
353 case '?': 414 else
354 dst_char = cpu_to_le16(UNI_QUESTION); 415 dst_char = 0;
355 break;
356 case '<':
357 dst_char = cpu_to_le16(UNI_LESSTHAN);
358 break;
359 case '>':
360 dst_char = cpu_to_le16(UNI_GRTRTHAN);
361 break;
362 case '|':
363 dst_char = cpu_to_le16(UNI_PIPE);
364 break;
365 /* 416 /*
366 * FIXME: We can not handle remapping backslash (UNI_SLASH) 417 * FIXME: We can not handle remapping backslash (UNI_SLASH)
367 * until all the calls to build_path_from_dentry are modified, 418 * until all the calls to build_path_from_dentry are modified,
368 * as they use backslash as separator. 419 * as they use backslash as separator.
369 */ 420 */
370 default: 421 if (dst_char == 0) {
371 charlen = cp->char2uni(source + i, srclen - i, &tmp); 422 charlen = cp->char2uni(source + i, srclen - i, &tmp);
372 dst_char = cpu_to_le16(tmp); 423 dst_char = cpu_to_le16(tmp);
373 424
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index 4aa7a0f07d6e..1a08a34838fc 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -379,6 +379,14 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
379 int len; 379 int len;
380 const char *start_of_path; 380 const char *start_of_path;
381 __le16 *to; 381 __le16 *to;
382 int map_type;
383
384 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
385 map_type = SFM_MAP_UNI_RSVD;
386 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
387 map_type = SFU_MAP_UNI_RSVD;
388 else
389 map_type = NO_MAP_UNI_RSVD;
382 390
383 /* Windows doesn't allow paths beginning with \ */ 391 /* Windows doesn't allow paths beginning with \ */
384 if (from[0] == '\\') 392 if (from[0] == '\\')
@@ -386,9 +394,7 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
386 else 394 else
387 start_of_path = from; 395 start_of_path = from;
388 to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, 396 to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
389 cifs_sb->local_nls, 397 cifs_sb->local_nls, map_type);
390 cifs_sb->mnt_cifs_flags &
391 CIFS_MOUNT_MAP_SPECIAL_CHR);
392 return to; 398 return to;
393} 399}
394 400