[PATCH 04/12] cifs: add new function to get unicode string length in bytes

Jeff Layton <[email protected]>
Newsgroups gmane.linux.file-systems.cifs
Message-ID <[email protected]>
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 <[email protected]>
---
 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 8389f35..6145125 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -26,6 +26,37 @@
 #include "cifs_debug.h"
 
 /*
+ * cifs_ucs2_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 ucs2le string and return the number of bytes that the string will
+ * be after being converted to the given charset, not including any null
+ * termination required. Don't walk past maxbytes in the source buffer.
+ */
+int
+cifs_ucs2_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 6aa6533..1857f5f 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -74,6 +74,8 @@ extern struct UniCaseRange UniLowerRange[];
 #ifdef __KERNEL__
 int cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
 		   const struct nls_table *codepage, bool mapchar);
+int cifs_ucs2_bytes(const __le16 *from, int maxbytes,
+		    const struct nls_table *codepage);
 int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
 int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
 #endif
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a02c43b..cadacae 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_ucs2_bytes(tmp,
+					le16_to_cpu(pSMBr->PathConsumed),
 					nls_codepage);
 			kfree(tmp);
 		} else
-- 
1.6.0.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.