[linux-cifs-client] [PATCH 04/10] cifs: add new function to get unicode string length in bytes

Jeff Layton jlayton at redhat.com
Wed Apr 29 13:29:14 GMT 2009


Working in units of words means we do a lot of unnecessary conversion back
and forth. Standardize on bytes instead since that's more useful for
allocating buffers and such. Also, remove hostlen_fromUCS since the new
function has a similar purpose.

Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
 fs/cifs/cifs_unicode.c |   31 +++++++++++++++++++++++++++++++
 fs/cifs/cifs_unicode.h |    2 ++
 fs/cifs/cifssmb.c      |   25 ++-----------------------
 3 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index aafaf0d..adb8e1f 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -26,6 +26,37 @@
 #include "cifs_debug.h"
 
 /*
+ * cifs_utf16le_bytes - how long will a string be after conversion?
+ * @ucs - pointer to input string
+ * @maxbytes - don't go past this many bytes of input string
+ * @codepage - destination codepage
+ *
+ * Walk a UCS2_le string and return the number of bytes that the string will
+ * be after being converted to the given charset. Don't walk past maxbytes
+ * in the source buffer.
+ */
+int
+cifs_utf16le_bytes(const __le16 *from, int maxbytes,
+		   const struct nls_table *codepage)
+{
+	int i;
+	int charlen, outlen = 0;
+	int maxwords = maxbytes / 2;
+	char tmp[NLS_MAX_CHARSET_SIZE];
+
+	for (i = 0; from[i] && i < maxwords; i++) {
+		charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,
+					     NLS_MAX_CHARSET_SIZE);
+		if (charlen > 0)
+			outlen += charlen;
+		else
+			outlen++;
+	}
+
+	return outlen;
+}
+
+/*
  * cifs_mapchar - convert a little-endian char to proper char in codepage
  * @target - where converted character should be copied
  * @src_char - 2 byte little-endian source character
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index e23ef08..9f1b91e 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -72,6 +72,8 @@ extern struct UniCaseRange UniLowerRange[];
 #endif				/* UNIUPR_NOLOWER */
 
 #ifdef __KERNEL__
+int cifs_utf16le_bytes(const __le16 *from, int maxbytes,
+		       const struct nls_table *codepage);
 int cifs_utf16le_to_host(char *to, const __le16 *from, int tolen, int fromlen,
 			 const struct nls_table *codepage, bool mapchar);
 int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a02c43b..256b5fe 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3928,27 +3928,6 @@ GetInodeNumOut:
 	return rc;
 }
 
-/* computes length of UCS string converted to host codepage
- * @src:	UCS string
- * @maxlen:	length of the input string in UCS characters
- * 		(not in bytes)
- *
- * return:	size of input string in host codepage
- */
-static int hostlen_fromUCS(const __le16 *src, const int maxlen,
-		const struct nls_table *nls_codepage) {
-	int i;
-	int hostlen = 0;
-	char to[4];
-	int charlen;
-	for (i = 0; (i < maxlen) && src[i]; ++i) {
-		charlen = nls_codepage->uni2char(le16_to_cpu(src[i]),
-				to, NLS_MAX_CHARSET_SIZE);
-		hostlen += charlen > 0 ? charlen : 1;
-	}
-	return hostlen;
-}
-
 /* parses DFS refferal V3 structure
  * caller is responsible for freeing target_nodes
  * returns:
@@ -4016,8 +3995,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
 						GFP_KERNEL);
 			cifsConvertToUCS((__le16 *) tmp, searchName,
 					PATH_MAX, nls_codepage, remap);
-			node->path_consumed = hostlen_fromUCS(tmp,
-					le16_to_cpu(pSMBr->PathConsumed)/2,
+			node->path_consumed = cifs_utf16le_bytes(tmp,
+					le16_to_cpu(pSMBr->PathConsumed),
 					nls_codepage);
 			kfree(tmp);
 		} else
-- 
1.6.0.6



More information about the linux-cifs-client mailing list