diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2009-04-30 10:08:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:43 -0400 |
commit | 74675a58507e769beee7d949dbed788af3c4139d (patch) | |
tree | d4ae3cc06dbfadecf1eaf6ed0aef249fc87b07e6 /fs/fat | |
parent | a853a3d4eb2edb066248a39f0634f6f5858816a0 (diff) |
NLS: update handling of Unicode
This patch (as1239) updates the kernel's treatment of Unicode. The
character-set conversion routines are well behind the current state of
the Unicode specification: They don't recognize the existence of code
points beyond plane 0 or of surrogate pairs in the UTF-16 encoding.
The old wchar_t 16-bit type is retained because it's still used in
lots of places. This shouldn't cause any new problems; if a
conversion now results in an invalid 16-bit code then before it must
have yielded an undefined code.
Difficult-to-read names like "utf_mbstowcs" are replaced with more
transparent names like "utf8s_to_utf16s" and the ordering of the
parameters is rationalized (buffer lengths come immediate after the
pointers they refer to, and the inputs precede the outputs).
Fortunately the low-level conversion routines are used in only a few
places; the interfaces to the higher-level uni2char and char2uni
methods have been left unchanged.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/fat')
-rw-r--r-- | fs/fat/dir.c | 29 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 4 |
2 files changed, 17 insertions, 16 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index f3500294eec5..7c14c8cbbaba 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -22,6 +22,19 @@ | |||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include "fat.h" | 23 | #include "fat.h" |
24 | 24 | ||
25 | /* | ||
26 | * Maximum buffer size of short name. | ||
27 | * [(MSDOS_NAME + '.') * max one char + nul] | ||
28 | * For msdos style, ['.' (hidden) + MSDOS_NAME + '.' + nul] | ||
29 | */ | ||
30 | #define FAT_MAX_SHORT_SIZE ((MSDOS_NAME + 1) * NLS_MAX_CHARSET_SIZE + 1) | ||
31 | /* | ||
32 | * Maximum buffer size of unicode chars from slots. | ||
33 | * [(max longname slots * 13 (size in a slot) + nul) * sizeof(wchar_t)] | ||
34 | */ | ||
35 | #define FAT_MAX_UNI_CHARS ((MSDOS_SLOTS - 1) * 13 + 1) | ||
36 | #define FAT_MAX_UNI_SIZE (FAT_MAX_UNI_CHARS * sizeof(wchar_t)) | ||
37 | |||
25 | static inline loff_t fat_make_i_pos(struct super_block *sb, | 38 | static inline loff_t fat_make_i_pos(struct super_block *sb, |
26 | struct buffer_head *bh, | 39 | struct buffer_head *bh, |
27 | struct msdos_dir_entry *de) | 40 | struct msdos_dir_entry *de) |
@@ -171,7 +184,8 @@ static inline int fat_uni_to_x8(struct msdos_sb_info *sbi, const wchar_t *uni, | |||
171 | unsigned char *buf, int size) | 184 | unsigned char *buf, int size) |
172 | { | 185 | { |
173 | if (sbi->options.utf8) | 186 | if (sbi->options.utf8) |
174 | return utf8_wcstombs(buf, uni, size); | 187 | return utf16s_to_utf8s(uni, FAT_MAX_UNI_CHARS, |
188 | UTF16_HOST_ENDIAN, buf, size); | ||
175 | else | 189 | else |
176 | return uni16_to_x8(buf, uni, size, sbi->options.unicode_xlate, | 190 | return uni16_to_x8(buf, uni, size, sbi->options.unicode_xlate, |
177 | sbi->nls_io); | 191 | sbi->nls_io); |
@@ -325,19 +339,6 @@ parse_long: | |||
325 | } | 339 | } |
326 | 340 | ||
327 | /* | 341 | /* |
328 | * Maximum buffer size of short name. | ||
329 | * [(MSDOS_NAME + '.') * max one char + nul] | ||
330 | * For msdos style, ['.' (hidden) + MSDOS_NAME + '.' + nul] | ||
331 | */ | ||
332 | #define FAT_MAX_SHORT_SIZE ((MSDOS_NAME + 1) * NLS_MAX_CHARSET_SIZE + 1) | ||
333 | /* | ||
334 | * Maximum buffer size of unicode chars from slots. | ||
335 | * [(max longname slots * 13 (size in a slot) + nul) * sizeof(wchar_t)] | ||
336 | */ | ||
337 | #define FAT_MAX_UNI_CHARS ((MSDOS_SLOTS - 1) * 13 + 1) | ||
338 | #define FAT_MAX_UNI_SIZE (FAT_MAX_UNI_CHARS * sizeof(wchar_t)) | ||
339 | |||
340 | /* | ||
341 | * Return values: negative -> error, 0 -> not found, positive -> found, | 342 | * Return values: negative -> error, 0 -> not found, positive -> found, |
342 | * value is the total amount of slots, including the shortname entry. | 343 | * value is the total amount of slots, including the shortname entry. |
343 | */ | 344 | */ |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index b50ecbe97f83..f92ad9995356 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -502,11 +502,11 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, | |||
502 | if (utf8) { | 502 | if (utf8) { |
503 | int name_len = strlen(name); | 503 | int name_len = strlen(name); |
504 | 504 | ||
505 | *outlen = utf8_mbstowcs((wchar_t *)outname, name, PATH_MAX); | 505 | *outlen = utf8s_to_utf16s(name, PATH_MAX, (wchar_t *) outname); |
506 | 506 | ||
507 | /* | 507 | /* |
508 | * We stripped '.'s before and set len appropriately, | 508 | * We stripped '.'s before and set len appropriately, |
509 | * but utf8_mbstowcs doesn't care about len | 509 | * but utf8s_to_utf16s doesn't care about len |
510 | */ | 510 | */ |
511 | *outlen -= (name_len - len); | 511 | *outlen -= (name_len - len); |
512 | 512 | ||