On Wed, Jan 19, 2011 at 9:58 AM, Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> wrote: > On Tue, Jan 18, 2011 at 2:33 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote: >> Make sure we use get/put_unaligned routines when accessing wide >> character strings. >> >> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> >> --- >> fs/cifs/cifs_unicode.c | 49 ++++++++++++++++++++++++++--------------------- >> 1 files changed, 27 insertions(+), 22 deletions(-) >> >> diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c >> index 430f510..8134443 100644 >> --- a/fs/cifs/cifs_unicode.c >> +++ b/fs/cifs/cifs_unicode.c >> @@ -44,10 +44,14 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes, >> int charlen, outlen = 0; >> int maxwords = maxbytes / 2; >> char tmp[NLS_MAX_CHARSET_SIZE]; >> + __u16 ftmp; >> >> - for (i = 0; i < maxwords && from[i]; i++) { >> - charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp, >> - NLS_MAX_CHARSET_SIZE); >> + for (i = 0; i < maxwords; i++) { >> + ftmp = get_unaligned_le16(&from[i]); >> + if (ftmp == 0) >> + break; >> + >> + charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE); >> if (charlen > 0) >> outlen += charlen; >> else >> @@ -60,7 +64,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes, >> /* >> * cifs_mapchar - convert a little-endian char to proper char in codepage > > I think this wording is now incorrect since src_char is not le anymore. > >> * @target - where converted character should be copied >> - * @src_char - 2 byte little-endian source character >> + * @src_char - 2 byte host-endian source character >> * @cp - codepage to which character should be converted >> * @mapchar - should character be mapped according to mapchars mount option? >> * >> @@ -69,7 +73,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes, >> * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE). >> */ >> static int >> -cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp, >> +cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, >> bool mapchar) >> { >> int len = 1; >> @@ -82,7 +86,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp, >> * build_path_from_dentry are modified, as they use slash as >> * separator. >> */ >> - switch (le16_to_cpu(src_char)) { >> + switch (src_char) { >> case UNI_COLON: >> *target = ':'; >> break; >> @@ -109,8 +113,7 @@ out: >> return len; >> >> cp_convert: >> - len = cp->uni2char(le16_to_cpu(src_char), target, >> - NLS_MAX_CHARSET_SIZE); >> + len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); >> if (len <= 0) { >> *target = '?'; >> len = 1; >> @@ -149,6 +152,7 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen, >> int nullsize = nls_nullsize(codepage); >> int fromwords = fromlen / 2; >> char tmp[NLS_MAX_CHARSET_SIZE]; >> + __u16 ftmp; >> >> /* >> * because the chars can be of varying widths, we need to take care >> @@ -158,19 +162,23 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen, >> */ >> safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize); >> >> - for (i = 0; i < fromwords && from[i]; i++) { >> + for (i = 0; i < fromwords; i++) { >> + ftmp = get_unaligned_le16(&from[i]); >> + if (ftmp == 0) >> + break; >> + > > Can the contents of from[i] be 0 so ftmp is 0 but we did > not want to break out until fromwords? > Basically, why_does/what_it_means get_unaligned_le16() returning 0 warrants breaking out of the loop! >> /* >> * check to see if converting this character might make the >> * conversion bleed into the null terminator >> */ >> if (outlen >= safelen) { >> - charlen = cifs_mapchar(tmp, from[i], codepage, mapchar); >> + charlen = cifs_mapchar(tmp, ftmp, codepage, mapchar); >> if ((outlen + charlen) > (tolen - nullsize)) >> break; >> } >> >> /* put converted char into 'to' buffer */ >> - charlen = cifs_mapchar(&to[outlen], from[i], codepage, mapchar); >> + charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar); >> outlen += charlen; >> } >> >> @@ -193,24 +201,21 @@ cifs_strtoUCS(__le16 *to, const char *from, int len, >> { >> int charlen; >> int i; >> - wchar_t *wchar_to = (wchar_t *)to; /* needed to quiet sparse */ >> + wchar_t wchar_to; /* needed to quiet sparse */ >> >> for (i = 0; len && *from; i++, from += charlen, len -= charlen) { >> - >> - /* works for 2.4.0 kernel or later */ >> - charlen = codepage->char2uni(from, len, &wchar_to[i]); >> + charlen = codepage->char2uni(from, len, &wchar_to); >> if (charlen < 1) { >> - cERROR(1, "strtoUCS: char2uni of %d returned %d", >> - (int)*from, charlen); >> + cERROR(1, "strtoUCS: char2uni of 0x%x returned %d", >> + *from, charlen); >> /* A question mark */ >> - to[i] = cpu_to_le16(0x003f); >> + wchar_to = 0x003f; >> charlen = 1; >> - } else >> - to[i] = cpu_to_le16(wchar_to[i]); >> - >> + } >> + put_unaligned_le16(wchar_to, &to[i]); >> } >> >> - to[i] = 0; >> + put_unaligned_le16(0, &to[i]); >> return i; >> } >> >> -- >> 1.7.3.4 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html