[PATCH 3/8] Support non-BMP characters in JFS.

From: Vladimir 'Ï-coder/phcoder' Serbinenko
Date: Tue May 15 2012 - 19:03:31 EST



Signed-off-by: Vladimir Serbinenko <phcoder@xxxxxxxxx>
---
fs/jfs/jfs_unicode.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
index 2d70cf1..70f667a 100644
--- a/fs/jfs/jfs_unicode.c
+++ b/fs/jfs/jfs_unicode.c
@@ -34,14 +34,23 @@ int jfs_strfromUCS_le(char *to, const __le16 * from,
{
int i;
int outlen = 0;
+ int step;
static int warn_again = 5; /* Only warn up to 5 times total */
int warn = !!warn_again; /* once per string */

if (codepage) {
- for (i = 0; (i < len) && from[i]; i++) {
+ for (i = 0; (i < len) && from[i]; ) {
int charlen;
+ unicode_t uni;
+ step = utf16s_to_unicode(from + i, len - i,
+ UTF16_LITTLE_ENDIAN,
+ &uni);
+ if (!step)
+ break;
+ i += step;
+
charlen =
- codepage->uni2char(le16_to_cpu(from[i]),
+ codepage->uni2char(uni,
&to[outlen],
NLS_MAX_CHARSET_SIZE);
if (charlen > 0)
@@ -86,18 +95,26 @@ static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len,
int i;

if (codepage) {
- for (i = 0; len && *from; i++, from += charlen, len -= charlen)
+ for (i = 0; len && *from; from += charlen, len -= charlen)
{
unicode_t uni;
+ int step;
charlen = codepage->char2uni(from, len, &uni);
- to[i] = uni;
- if (charlen < 1 || uni > 0xffff) {
+ if (charlen < 1) {
jfs_err("jfs_strtoUCS: char2uni returned %d.",
charlen);
jfs_err("charset = %s, char = 0x%x",
codepage->charset, *from);
return charlen;
}
+ step = unicode_to_utf16s(uni, UTF16_HOST_ENDIAN,
+ to + i, MAX_UTF16_PER_UNICODE);
+ if (step < 0) {
+ jfs_err("jfs_strtoUCS: unicode_to_utf16s returned %d.",
+ step);
+ return step;
+ }
+ i += step;
}
} else {
for (i = 0; (i < len) && from[i]; i++)
@@ -123,7 +140,8 @@ int get_UCSname(struct component_name * uniName, struct dentry *dentry)
return -ENAMETOOLONG;

uniName->name =
- kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
+ kmalloc((length * MAX_UTF16_PER_UNICODE + 1) * sizeof(wchar_t),
+ GFP_NOFS);

if (uniName->name == NULL)
return -ENOMEM;
--
1.7.10

--
Regards
Vladimir 'Ï-coder/phcoder' Serbinenko

Attachment: signature.asc
Description: OpenPGP digital signature