linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] 2.4.8-pre3 NTFS update (1.1.16)
@ 2001-08-01  3:51 ` Anton Altaparmakov
  2001-08-01 10:40   ` Urban Widmark
  2001-08-01 18:21   ` Anton Altaparmakov
  0 siblings, 2 replies; 3+ messages in thread
From: Anton Altaparmakov @ 2001-08-01  3:51 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=US-ASCII, Size: 26657 bytes --]

Hello Linus,

Please apply below patch which updates the NTFS driver. Patch is against
2.4.8-pre3, doesn't touch any non-NTFS code and is successfully tested
with the NTFS filesystems I threw at it.

Detailed description of patch:

- Removed non-functional uni_xlate mount options.
- Clarified the semantics of the utf8 and iocharset mount options.
- Threw out the non-functional mount options for using hard coded 
character set conversion. Only kept utf8 one.
- Fixed handling of mount options and proper handling of faulty mount 
options on remount.
- Cleaned up character conversion which basically became simplified a lot
due to the removal of the above mentioned mount options.
- Made character conversion to be always consistent. Previously we could
output to the VFS file names which we would then not accept back from the
VFS so in effect we were generating ghost entries in the directory 
listings which could not be accessed by any means.
- Simplified time conversion functions drastically without
sacrificing accuracy, now the offending function is 3 lines instead of
two pages of code. (-8
- Fixed a use of a pointer before the check for the pointer being NULL,
reported by the Stanford checker.

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Linux NTFS maintainer / WWW: http://linux-ntfs.sf.net/
ICQ: 8561279 / WWW: http://www-stu.christs.cam.ac.uk/~aia21/
  
------linux-2.4.8-pre3-ntfs-1.1.16.diff------

diff -urN linux-2.4.8-pre3.vanilla/fs/ntfs/dir.c linux-2.4.8-pre3.tmd/fs/ntfs/dir.c
--- linux-2.4.8-pre3.vanilla/fs/ntfs/dir.c	Tue Jul 31 18:24:04 2001
+++ linux-2.4.8-pre3.tmd/fs/ntfs/dir.c	Tue Jul 31 17:39:45 2001
@@ -789,7 +789,7 @@
 	int block;
 	int start;
 	ntfs_attribute *attr;
-	ntfs_volume *vol = ino->vol;
+	ntfs_volume *vol;
 	int byte, bit;
 	int error = 0;
 
@@ -797,6 +797,7 @@
 		ntfs_error("No inode passed to getdir_unsorted\n");
 		return -EINVAL;
 	}
+       	vol = ino->vol;
 	if (!vol) {
 		ntfs_error("Inode %d has no volume\n", ino->i_number);
 		return -EINVAL;
diff -urN linux-2.4.8-pre3.vanilla/fs/ntfs/support.c linux-2.4.8-pre3.tmd/fs/ntfs/support.c
--- linux-2.4.8-pre3.vanilla/fs/ntfs/support.c	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/fs/ntfs/support.c	Tue Jul 31 17:36:16 2001
@@ -225,147 +225,81 @@
 	return ntfs_unixutc2ntutc(CURRENT_TIME);
 }
 
-/* When printing unicode characters base64, use this table. It is not strictly
- * base64, but the Linux vfat encoding. base64 has the disadvantage of using
- * the slash. */
-static char uni2esc[64] = 
-	    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-";
-
-static unsigned char esc2uni(char c)
-{
-	if (c <  '0') return 255;
-	if (c <= '9') return c - '0';
-	if (c <  'A') return 255;
-	if (c <= 'Z') return c - 'A' + 10;
-	if (c <  'a') return 255;
-	if (c <= 'z') return c - 'a' + 36;
-	if (c == '+') return 62;
-	if (c == '-') return 63;
-	return 255;
-}
-
 int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
-		    int *out_len)
+		int *out_len)
 {
-	int i, o, val, chl, chi;
+	int i, o, chl, chi;
 	char *result, *buf, charbuf[NLS_MAX_CHARSET_SIZE];
-	struct nls_table* nls = vol->nls_map;
+	struct nls_table *nls = vol->nls_map;
 
 	result = ntfs_malloc(in_len + 1);
 	if (!result)
 		return -ENOMEM;
 	*out_len = in_len;
-	result[in_len] = '\0';
 	for (i = o = 0; i < in_len; i++) {
-		int cl, ch;
-		/* FIXME: byte order? */
-		cl = in[i] & 0xFF;
-		ch = (in[i] >> 8) & 0xFF;
-		if (!nls) {
-			if (!ch) {
-				result[o++] = cl;
-				continue;
-			}
-		} else {
-			/* FIXME: byte order? */
-			wchar_t uni = in[i];
-			if ((chl = nls->uni2char(uni, charbuf,
-						NLS_MAX_CHARSET_SIZE)) > 0) {
-				/* adjust result buffer */
-				if (chl > 1) {
-					buf = ntfs_malloc(*out_len + chl - 1);
-					if (!buf) {
-						ntfs_free(result);
-						return -ENOMEM;
-					}
-					memcpy(buf, result, o);
+		/* FIXME: Byte order? */
+		wchar_t uni = in[i];
+		if ((chl = nls->uni2char(uni, charbuf,
+				NLS_MAX_CHARSET_SIZE)) > 0) {
+			/* Adjust result buffer. */
+			if (chl > 1) {
+				buf = ntfs_malloc(*out_len + chl - 1);
+				if (!buf) {
 					ntfs_free(result);
-					result = buf;
-					*out_len += (chl - 1);
+					return -ENOMEM;
 				}
-				for (chi = 0; chi < chl; chi++)
-					result[o++] = charbuf[chi];
-			} else
-				result[o++] = '?';
-			continue;
-		}
-		if (!(vol->nct & nct_uni_xlate))
-			goto inval;
-		/* realloc */
-		buf = ntfs_malloc(*out_len + 3);
-		if (!buf) {
-			ntfs_free(result);
-			return -ENOMEM;
-		}
-		memcpy(buf, result, o);
-		ntfs_free(result);
-		result = buf;
-		*out_len += 3;
-		result[o++] = ':';
-		if (vol->nct & nct_uni_xlate_vfat) {
-			val = (cl << 8) + ch;
-			result[o+2] = uni2esc[val & 0x3f];
-			val >>= 6;
-			result[o+1] = uni2esc[val & 0x3f];
-			val >>= 6;
-			result[o] = uni2esc[val & 0x3f];
-			o += 3;
+				memcpy(buf, result, o);
+				ntfs_free(result);
+				result = buf;
+				*out_len += (chl - 1);
+			}
+			for (chi = 0; chi < chl; chi++)
+				result[o++] = charbuf[chi];
 		} else {
-			val = (ch << 8) + cl;
-			result[o++] = uni2esc[val & 0x3f];
-			val >>= 6;
-			result[o++] = uni2esc[val & 0x3f];
-			val >>= 6;
-			result[o++] = uni2esc[val & 0x3f];
+			/* Invalid character. */
+			printk(KERN_ERR "NTFS: Unicode name contains a "
+					"character that cannot be converted "
+					"to chosen character set. Remount "
+					"with utf8 encoding and this should "
+					"work.\n");
+			ntfs_free(result);
+			return -EILSEQ;
 		}
 	}
+	result[*out_len] = '\0';
 	*out = result;
 	return 0;
- inval:
-	ntfs_free(result);
-	*out = 0;
-	return -EILSEQ;
 }
 
 int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out,
-		    int *out_len)
+		int *out_len)
 {
 	int i, o;
-	ntfs_u16* result;
-	struct nls_table* nls = vol->nls_map;
+	ntfs_u16 *result;
+	struct nls_table *nls = vol->nls_map;
 
-	*out=result = ntfs_malloc(2 * in_len);
+	*out = result = ntfs_malloc(2 * in_len);
 	if (!result)
 		return -ENOMEM;
 	*out_len = in_len;
-	for (i = o = 0; i < in_len; i++, o++){
+	for (i = o = 0; i < in_len; i++, o++) {
 		wchar_t uni;
-		if (in[i] != ':' || (vol->nct & nct_uni_xlate) == 0){
-			int charlen;
-			charlen = nls->char2uni(&in[i], in_len-i, &uni);
-			if (charlen < 0)
-				return charlen;
-			*out_len -= (charlen - 1);
-			i += (charlen - 1);
-		} else {
-			unsigned char c1, c2, c3;
-			*out_len -= 3;
-			c1 = esc2uni(in[++i]);
-			c2 = esc2uni(in[++i]);
-			c3 = esc2uni(in[++i]);
-			if (c1 == 255 || c2 == 255 || c3 == 255)
-				uni = 0;
-			else if (vol->nct & nct_uni_xlate_vfat) {
-				uni = (((c2 & 0x3) << 6) + c3) << 8 |
-				      ((c1 << 4) + (c2 >> 2));
-			} else {
-				uni = ((c3 << 4) + (c2 >> 2)) << 8 |
-				      (((c2 & 0x3) << 6) + c1);
-			}
+		int charlen;
+
+		charlen = nls->char2uni(&in[i], in_len - i, &uni);
+		if (charlen < 0) {
+			printk(KERN_ERR "NTFS: Name contains a character that "
+					"cannot be converted to Unicode.\n");
+			ntfs_free(result);
+			return charlen;
 		}
-		/* FIXME: byte order? */
+		*out_len -= charlen - 1;
+		i += charlen - 1;
+		/* FIXME: Byte order? */
 		result[o] = uni;
 		if (!result[o]) {
+			printk(KERN_ERR "NTFS: Name contains a character that "
+					"cannot be converted to Unicode.\n");
 			ntfs_free(result);
 			return -EILSEQ;
 		}
diff -urN linux-2.4.8-pre3.vanilla/fs/ntfs/util.c linux-2.4.8-pre3.tmd/fs/ntfs/util.c
--- linux-2.4.8-pre3.vanilla/fs/ntfs/util.c	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/fs/ntfs/util.c	Tue Jul 31 17:37:59 2001
@@ -13,12 +13,15 @@
 #include "util.h"
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <asm/div64.h>		/* For do_div(). */
 #include "support.h"
 
-/* Converts a single wide character to a sequence of utf8 bytes.
+/*
+ * Converts a single wide character to a sequence of utf8 bytes.
  * The character is represented in host byte order.
- * Returns the number of bytes, or 0 on error. */
-static int to_utf8(ntfs_u16 c, unsigned char* buf)
+ * Returns the number of bytes, or 0 on error.
+ */
+static int to_utf8(ntfs_u16 c, unsigned char *buf)
 {
 	if (c == 0)
 		return 0; /* No support for embedded 0 runes. */
@@ -34,22 +37,21 @@
 		}
 		return 2;
 	}
-	if (c < 0x10000) {
-		if (buf) {
-			buf[0] = 0xe0 | (c >> 12);
-			buf[1] = 0x80 | ((c >> 6) & 0x3f);
-			buf[2] = 0x80 | (c & 0x3f);
-		}
-		return 3;
+	/* c < 0x10000 */
+	if (buf) {
+		buf[0] = 0xe0 | (c >> 12);
+		buf[1] = 0x80 | ((c >> 6) & 0x3f);
+		buf[2] = 0x80 | (c & 0x3f);
 	}
-	/* We don't support characters above 0xFFFF in NTFS. */
-	return 0;
+	return 3;
 }
 
-/* Decodes a sequence of utf8 bytes into a single wide character.
+/*
+ * Decodes a sequence of utf8 bytes into a single wide character.
  * The character is returned in host byte order.
- * Returns the number of bytes consumed, or 0 on error. */
-static int from_utf8(const unsigned char* str, ntfs_u16 *c)
+ * Returns the number of bytes consumed, or 0 on error.
+ */
+static int from_utf8(const unsigned char *str, ntfs_u16 *c)
 {
 	int l = 0, i;
 
@@ -80,11 +82,12 @@
 	return l;
 }
 
-/* Converts wide string to UTF-8. Expects two in- and two out-parameters.
+/*
+ * Converts wide string to UTF-8. Expects two in- and two out-parameters.
  * Returns 0 on success, or error code. 
  * The caller has to free the result string.
- * There is no support for UTF-16, yet. */
-static int ntfs_dupuni2utf8(ntfs_u16* in, int in_len, char **out, int *out_len)
+ */
+static int ntfs_dupuni2utf8(ntfs_u16 *in, int in_len, char **out, int *out_len)
 {
 	int i, tmp;
 	int len8;
@@ -92,15 +95,14 @@
 
 	ntfs_debug(DEBUG_NAME1, "converting l = %d\n", in_len);
 	/* Count the length of the resulting UTF-8. */
-	for (i = len8 = 0; i < in_len; i++){
+	for (i = len8 = 0; i < in_len; i++) {
 		tmp = to_utf8(NTFS_GETU16(in + i), 0);
 		if (!tmp)
-			/* invalid character */
+			/* Invalid character. */
 			return -EILSEQ;
 		len8 += tmp;
 	}
 	*out = result = ntfs_malloc(len8 + 1); /* allow for zero-termination */
-
 	if (!result)
 		return -ENOMEM;
 	result[len8] = '\0';
@@ -111,10 +113,12 @@
 	return 0;
 }
 
-/* Converts an UTF-8 sequence to a wide string. Same conventions as the
- * previous function. */
+/*
+ * Converts an UTF-8 sequence to a wide string. Same conventions as the
+ * previous function.
+ */
 static int ntfs_duputf82uni(unsigned char* in, int in_len, ntfs_u16** out,
-			    int *out_len)
+		int *out_len)
 {
 	int i, tmp;
 	int len16;
@@ -131,76 +135,30 @@
 		return -ENOMEM;
 	result[len16] = 0;
 	*out_len = len16;
-	for (i = len16 = 0; i < in_len; i += tmp, len16++)
-	{
+	for (i = len16 = 0; i < in_len; i += tmp, len16++) {
 		tmp = from_utf8(in + i, &wtmp);
 		NTFS_PUTU16(result + len16, wtmp);
 	}
 	return 0;
 }
 
-/* See above. Produces ISO-8859-1 from wide strings. */
-static int ntfs_dupuni288591(ntfs_u16* in, int in_len, char** out, int *out_len)
-{
-	int i;
-	char *result;
-
-	/* Check for characters out of range. */
-	for (i = 0; i < in_len; i++)
-		if (NTFS_GETU16(in + i) >= 256)
-			return -EILSEQ;
-	*out = result = ntfs_malloc(in_len + 1);
-	if (!result)
-		return -ENOMEM;
-	result[in_len] = '\0';
-	*out_len = in_len;
-	for (i = 0; i < in_len; i++)
-		result[i] = (unsigned char)NTFS_GETU16(in + i);
-	return 0;
-}
-
-/* See above. */
-static int ntfs_dup885912uni(unsigned char* in, int in_len, ntfs_u16 **out,
-			     int *out_len)
-{
-	int i;
-
-	ntfs_u16* result;
-	*out = result = ntfs_malloc(2 * in_len);
-	if (!result)
-		return -ENOMEM;
-	*out_len = in_len;
-	for (i = 0; i < in_len; i++)
-		NTFS_PUTU16(result + i, in[i]);
-	return 0;
-}
-
-/* Encodings dispatcher */
+/* Encodings dispatchers. */
 int ntfs_encodeuni(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
-		   int *out_len)
+		int *out_len)
 {
-	if (vol->nct & nct_utf8)
-		return ntfs_dupuni2utf8(in, in_len, out, out_len);
-	else if (vol->nct & nct_iso8859_1)
-		return ntfs_dupuni288591(in, in_len, out, out_len);
-	else if(vol->nct & (nct_map | nct_uni_xlate))
-		/* uni_xlate is handled inside map. */
+	if (vol->nls_map)
 		return ntfs_dupuni2map(vol, in, in_len, out, out_len);
 	else
-		return -EINVAL; /* unknown encoding */
+		return ntfs_dupuni2utf8(in, in_len, out, out_len);
 }
 
 int ntfs_decodeuni(ntfs_volume *vol, char *in, int in_len, ntfs_u16 **out,
-		   int *out_len)
+		int *out_len)
 {
-	if (vol->nct & nct_utf8)
-		return ntfs_duputf82uni(in, in_len, out, out_len);
-	else if (vol->nct & nct_iso8859_1)
-		return ntfs_dup885912uni(in, in_len, out, out_len);
-	else if (vol->nct & (nct_map | nct_uni_xlate))
+	if (vol->nls_map)
 		return ntfs_dupmap2uni(vol, in, in_len, out, out_len);
 	else
-		return -EINVAL;
+		return ntfs_duputf82uni(in, in_len, out, out_len);
 }
 
 /* Same address space copies. */
@@ -224,18 +182,6 @@
 	return result;
 }
 
-#if 0
-/* Copy len unicode characters from from to to. :) */
-void ntfs_uni2ascii(char *to, short int *from, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		to[i] = NTFS_GETU16(from + i);
-	to[i] = '\0';
-}
-#endif
-
 /* Copy len ascii characters from from to to. :) */
 void ntfs_ascii2uni(short int *to, char *from, int len)
 {
@@ -279,57 +225,26 @@
 	return 0;
 }
 
+#define NTFS_TIME_OFFSET ((ntfs_time64_t)(369*365 + 89) * 24 * 3600 * 10000000)
+
 /* Convert the NT UTC (based 1.1.1601, in hundred nanosecond units)
  * into Unix UTC (based 1.1.1970, in seconds). */
 ntfs_time_t ntfs_ntutc2unixutc(ntfs_time64_t ntutc)
 {
-/* This is very gross because:
- * 1: We must do 64-bit division on a 32-bit machine.
- * 2: We can't use libgcc for long long operations in the kernel.
- * 3: Floating point math in the kernel would corrupt user data. */
-	const unsigned int D = 10000000;
-	unsigned int H = (unsigned int)(ntutc >> 32);
-	unsigned int L = (unsigned int)ntutc;
-	unsigned int numerator2;
-	unsigned int lowseconds;
-	unsigned int result;
-
-	/* It is best to subtract 0x019db1ded53e8000 first. */
-	/* Then the 1601-based date becomes a 1970-based date. */
-	if (L < (unsigned)0xd53e8000)
-		H--;
-	L -= (unsigned)0xd53e8000;
-	H -= (unsigned)0x019db1de;
-
-	/* Now divide 64-bit numbers on a 32-bit machine. :-)
-	 * With the subtraction already done, the result fits in 32 bits.
-	 * The numerator fits in 56 bits and the denominator fits
-	 * in 24 bits, so we can shift by 8 bits to make this work. */
-
-	numerator2  = (H << 8) | (L >> 24);
-	result      = (numerator2 / D);   /* shifted 24 right!! */
-	lowseconds  = result << 24;
-
-	numerator2  = ((numerator2 - result * D) << 8) | ((L >> 16) & 0xff);
-	result      = (numerator2 / D);   /* shifted 16 right!! */
-	lowseconds |= result << 16;
-
-	numerator2  = ((numerator2 - result * D) << 8) | ((L >> 8) & 0xff);
-	result      = (numerator2 / D);   /* shifted 8 right!! */
-	lowseconds |= result << 8;
-
-	numerator2  = ((numerator2 - result * D) << 8) | (L & 0xff);
-	result      = (numerator2 / D);   /* not shifted */
-	lowseconds |= result;
-
-	return lowseconds;
+	/* Subtract the NTFS time offset, then convert to 1s intervals. */
+	ntfs_time64_t t = ntutc - NTFS_TIME_OFFSET;
+	do_div(t, 10000000);
+	return (ntfs_time_t)t;
 }
 
 /* Convert the Unix UTC into NT UTC. */
 ntfs_time64_t ntfs_unixutc2ntutc(ntfs_time_t t)
 {
-	return ((t + (ntfs_time64_t)(369 * 365 + 89) * 24 * 3600) * 10000000);
+	/* Convert to 100ns intervals and then add the NTFS time offset. */
+	return (ntfs_time64_t)t * 10000000 + NTFS_TIME_OFFSET;
 }
+
+#undef NTFS_TIME_OFFSET
 
 /* Fill index name. */
 void ntfs_indexname(char *buf, int type)
diff -urN linux-2.4.8-pre3.vanilla/fs/ntfs/util.h linux-2.4.8-pre3.tmd/fs/ntfs/util.h
--- linux-2.4.8-pre3.vanilla/fs/ntfs/util.h	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/fs/ntfs/util.h	Tue Jul 31 17:12:43 2001
@@ -5,18 +5,6 @@
  * Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
-/* Which character set is used for file names. */
-/*  Translate everything to UTF-8. */
-#define nct_utf8             1
-/*  Translate to 8859-1. */
-#define nct_iso8859_1        2
-/*  Quote unprintables with ":". */
-#define nct_uni_xlate        4
-/*  Do that in the vfat way instead of the documented way. */
-#define nct_uni_xlate_vfat   8
-/*  Use a mapping table to determine printables. */
-#define nct_map              16
-
 /* The first 16 inodes correspond to NTFS special files. */
 typedef enum {
 	FILE_$Mft	= 0,
@@ -42,9 +30,6 @@
 
 /* String operations */
 /*  Copy Unicode <-> ASCII */
-#if 0
-void ntfs_uni2ascii(char *to, char *from, int len);
-#endif
 void ntfs_ascii2uni(short int *to, char *from, int len);
 
 /*  Comparison */
diff -urN linux-2.4.8-pre3.vanilla/include/linux/ntfs_fs_sb.h linux-2.4.8-pre3.tmd/include/linux/ntfs_fs_sb.h
--- linux-2.4.8-pre3.vanilla/include/linux/ntfs_fs_sb.h	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/include/linux/ntfs_fs_sb.h	Tue Jul 31 15:42:21 2001
@@ -8,7 +8,6 @@
 	ntfs_uid_t uid;
 	ntfs_gid_t gid;
 	ntmode_t umask;
-        unsigned int nct;
 	void *nls_map;
 	unsigned int ngt;
 	/* Configuration provided by user with the ntfstools.
diff -urN linux-2.4.8-pre3.vanilla/fs/ntfs/fs.c linux-2.4.8-pre3.tmd/fs/ntfs/fs.c
--- linux-2.4.8-pre3.vanilla/fs/ntfs/fs.c	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/fs/ntfs/fs.c	Tue Jul 31 18:37:45 2001
@@ -1,8 +1,8 @@
 /*
  * fs.c - NTFS driver for Linux 2.4.x
  *
- * Development has as of recently (since June '01) been sponsored
- * by Legato Systems, Inc. (http://www.legato.com)
+ * Legato Systems, Inc. (http://www.legato.com) have sponsored Anton
+ * Altaparmakov to develop NTFS on Linux since June 2001.
  *
  * Copyright (C) 1995-1997, 1999 Martin von Löwis
  * Copyright (C) 1996 Richard Russon
@@ -286,25 +286,25 @@
 }
 
 /* Parse the (re)mount options. */
-static int parse_options(ntfs_volume* vol, char *opt)
+static int parse_options(ntfs_volume *vol, char *opt, int remount)
 {
-	char *value;
-
-	vol->uid = vol->gid = 0;
-	vol->umask = 0077;
-	vol->ngt = ngt_nt;
-	vol->nls_map = 0;
-	vol->nct = 0;
+	char *value;		/* Defaults if not specified and !remount. */
+	ntfs_uid_t uid = -1;	/* 0, root user only */
+	ntfs_gid_t gid = -1;	/* 0, root user only */
+	int umask = -1;		/* 0077, owner access only */
+	unsigned int ngt = -1;	/* ngt_nt */
+	void *nls_map = NULL;	/* Try to load the default NLS. */
+	int use_utf8 = -1;	/* If no NLS specified and loading the default
+				   NLS failed use utf8. */
 	if (!opt)
 		goto done;
-	for (opt = strtok(opt, ","); opt; opt = strtok(NULL, ","))
-	{
+	for (opt = strtok(opt, ","); opt; opt = strtok(NULL, ",")) {
 		if ((value = strchr(opt, '=')) != NULL)
 			*value ++= '\0';
 		if (strcmp(opt, "uid") == 0) {
 			if (!value || !*value)
 				goto needs_arg;
-			vol->uid = simple_strtoul(value, &value, 0);
+			uid = simple_strtoul(value, &value, 0);
 			if (*value) {
 				printk(KERN_ERR "NTFS: uid invalid argument\n");
 				return 0;
@@ -312,7 +312,7 @@
 		} else if (strcmp(opt, "gid") == 0) {
 			if (!value || !*value)
 				goto needs_arg;
-			vol->gid = simple_strtoul(value, &value, 0);
+			gid = simple_strtoul(value, &value, 0);
 			if (*value) {
 				printk(KERN_ERR "NTFS: gid invalid argument\n");
 				return 0;
@@ -320,79 +320,86 @@
 		} else if (strcmp(opt, "umask") == 0) {
 			if (!value || !*value)
 				goto needs_arg;
-			vol->umask = simple_strtoul(value, &value, 0);
+			umask = simple_strtoul(value, &value, 0);
 			if (*value) {
 				printk(KERN_ERR "NTFS: umask invalid "
 						"argument\n");
 				return 0;
 			}
-		} else if (strcmp(opt, "iocharset") == 0) {
-			if (!value || !*value)
-				goto needs_arg;
-			vol->nls_map = load_nls(value);
-			vol->nct |= nct_map;
-			if (!vol->nls_map) {
-				printk(KERN_ERR "NTFS: charset not found");
-				return 0;
-			}
 		} else if (strcmp(opt, "posix") == 0) {
 			int val;
 			if (!value || !*value)
 				goto needs_arg;
 			if (!simple_getbool(value, &val))
 				goto needs_bool;
-			vol->ngt = val ? ngt_posix : ngt_nt;
+			ngt = val ? ngt_posix : ngt_nt;
 		} else if (strcmp(opt, "show_sys_files") == 0) {
 			int val = 0;
 			if (!value || !*value)
 				val = 1;
 			else if (!simple_getbool(value, &val))
 				goto needs_bool;
-			vol->ngt = val ? ngt_full : ngt_nt;
-		} else if (strcmp(opt, "utf8") == 0) {
-			int val = 0;
+			ngt = val ? ngt_full : ngt_nt;
+		} else if (strcmp(opt, "iocharset") == 0) {
 			if (!value || !*value)
-				val = 1;
-			else if (!simple_getbool(value, &val))
-				goto needs_bool;
-			if (val)
-				vol->nct |= nct_utf8;
-		} else if (strcmp(opt, "uni_xlate") == 0) {
+				goto needs_arg;
+			nls_map = load_nls(value);
+			if (!nls_map) {
+				printk(KERN_ERR "NTFS: charset not found");
+				return 0;
+			}
+		} else if (strcmp(opt, "utf8") == 0) {
 			int val = 0;
-			/* No argument: uni_vfat. boolean argument: uni_vfat.
-			 * "2": uni. */
 			if (!value || !*value)
 				val = 1;
-			else if (strcmp(value, "2") == 0)
-				vol->nct |= nct_uni_xlate;
 			else if (!simple_getbool(value, &val))
 				goto needs_bool;
-			if (val)
-				vol->nct |= nct_uni_xlate_vfat | nct_uni_xlate;
+			use_utf8 = val;
 		} else {
 			printk(KERN_ERR "NTFS: unkown option '%s'\n", opt);
 			return 0;
 		}
 	}
-	if (vol->nct & nct_utf8 & (nct_map | nct_uni_xlate)) {
-		printk(KERN_ERR "utf8 cannot be combined with iocharset or "
-				"uni_xlate\n");
-		return 0;
-	}
- done:
-	if ((vol->nct & (nct_uni_xlate | nct_map | nct_utf8)) == 0)
-		/* default to UTF-8 */
-		vol->nct = nct_utf8;
-	if (!vol->nls_map) {
-		vol->nls_map = load_nls_default();
-		if (vol->nls_map)
-			vol->nct = nct_map | (vol->nct&nct_uni_xlate);
-	}
+done:
+	if (use_utf8 != -1 && use_utf8) {
+		if (nls_map) {
+			unload_nls(nls_map);
+			printk(KERN_ERR "NTFS: utf8 cannot be combined with "
+					"iocharset.\n");
+			return 0;
+		}
+		if (remount && vol->nls_map)
+			unload_nls(vol->nls_map);
+		vol->nls_map = NULL;
+	} else {
+		if (nls_map) {
+			if (remount && vol->nls_map)
+				unload_nls(vol->nls_map);
+			vol->nls_map = nls_map;
+		} else if (!remount || (remount && !use_utf8 && !vol->nls_map))
+			vol->nls_map = load_nls_default();
+	}
+	if (uid != -1)
+		vol->uid = uid;
+	else if (!remount)
+		vol->uid = 0;
+	if (gid != -1)
+		vol->gid = gid;
+	else if (!remount)
+		vol->gid = 0;
+	if (umask != -1)
+		vol->umask = (ntmode_t)umask;
+	else if (!remount)
+		vol->umask = 0077;
+	if (ngt != -1)
+		vol->ngt = ngt;
+	else if (!remount)
+		vol->ngt = ngt_nt;
 	return 1;
- needs_arg:
+needs_arg:
 	printk(KERN_ERR "NTFS: %s needs an argument", opt);
 	return 0;
- needs_bool:
+needs_bool:
 	printk(KERN_ERR "NTFS: %s needs boolean argument", opt);
 	return 0;
 }
@@ -898,7 +905,7 @@
 /* Called when remounting a filesystem by do_remount_sb() in fs/super.c. */
 static int ntfs_remount_fs(struct super_block *sb, int *flags, char *options)
 {
-	if (!parse_options(NTFS_SB2VOL(sb), options))
+	if (!parse_options(NTFS_SB2VOL(sb), options, 1))
 		return -EINVAL;
 	return 0;
 }
@@ -1003,7 +1010,7 @@
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");
 	vol = NTFS_SB2VOL(sb);
-	if (!parse_options(vol, (char*)options))
+	if (!parse_options(vol, (char*)options, 0))
 		goto ntfs_read_super_vol;
 	/* Assume a 512 bytes block device for now. */
 	set_blocksize(sb->s_dev, 512);
diff -urN linux-2.4.8-pre3.vanilla/fs/ntfs/Makefile linux-2.4.8-pre3.tmd/fs/ntfs/Makefile
--- linux-2.4.8-pre3.vanilla/fs/ntfs/Makefile	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/fs/ntfs/Makefile	Tue Jul 31 18:34:51 2001
@@ -5,7 +5,7 @@
 obj-y   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o unistr.o
 obj-m   := $(O_TARGET)
 # New version format started 3 February 2001.
-EXTRA_CFLAGS = -DNTFS_VERSION=\"1.1.15\" #-DDEBUG
+EXTRA_CFLAGS = -DNTFS_VERSION=\"1.1.16\" #-DDEBUG
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.8-pre3.vanilla/Documentation/filesystems/ntfs.txt linux-2.4.8-pre3.tmd/Documentation/filesystems/ntfs.txt
--- linux-2.4.8-pre3.vanilla/Documentation/filesystems/ntfs.txt	Mon Jul 16 23:14:10 2001
+++ linux-2.4.8-pre3.tmd/Documentation/filesystems/ntfs.txt	Tue Jul 31 18:36:52 2001
@@ -1,8 +1,8 @@
 NTFS Overview
 =============
 
-Driver development has as of recently (since June '01) been sponsored
-by Legato Systems, Inc. (http://www.legato.com)
+Legato Systems, Inc. (http://www.legato.com) have sponsored Anton Altaparmakov
+to develop NTFS on Linux since June 2001.
 
 To mount an NTFS volume, use the filesystem type 'ntfs'. The driver
 currently works only in read-only mode, with no fault-tolerance supported.
@@ -36,15 +36,17 @@
 
 iocharset=name		Character set to use when returning file names.
 			Unlike VFAT, NTFS suppresses names that contain
-			unconvertible characters
-
-utf8=<bool>		Use UTF-8 for converting file names
-
-uni_xlate=<bool>,2	Use the VFAT-style encoding for file names outside
-			the current character set. A boolean value will
-			enable the feature, a value of 2 will enable the
-			encoding as documented in vfat.txt:
-				':', (u & 0x3f), ((u>>6) & 0x3f), (u>>12),
+			unconvertible characters. Note that most character
+			sets contain insufficient characters to represent all
+			possible Unicode characters that can exist on NTFS. To
+			be sure you are not missing any files, you are advised
+			to use the iocharset=utf8 which should be capable of
+			representing all Unicode characters.
+
+utf8=<bool>		Use UTF-8 for converting file names. - It is preferable
+			to use iocharset=utf8 instead, but if the utf8 NLS is
+			not available, you can use this utf8 option, which
+			enables the driver's builtin utf8 conversion functions.
 
 uid=
 gid=
@@ -80,6 +82,27 @@
 
 ChangeLog
 =========
+
+NTFS 1.1.16:
+
+	- Removed non-functional uni_xlate mount options.
+	- Clarified the semantics of the utf8 and iocharset mount options.
+	- Threw out the non-functional mount options for using hard coded
+	  character set conversion. Only kept utf8 one.
+	- Fixed handling of mount options and proper handling of faulty mount
+	  options on remount.
+	- Cleaned up character conversion which basically became simplified a
+	  lot due to the removal of the above mentioned mount options.
+	- Made character conversion to be always consistent. Previously we
+	  could output to the VFS file names which we would then not accept
+	  back from the VFS so in effect we were generating ghost entries in
+	  the directory listings which could not be accessed by any means.
+	- Simplified time conversion functions drastically without sacrificing
+	  accuracy. (-8
+	- Fixed a use of a pointer before the check for the pointer being
+	  NULL, reported by the Stanford checker.
+	- Fixed several missing error checks, reported by the Stanford
+	  checker and fixed by Rasmus Andersen.
 
 NTFS 1.1.15 (changes since kernel 2.4.4's NTFS driver):
 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] 2.4.8-pre3 NTFS update (1.1.16)
  2001-08-01  3:51 ` [PATCH] 2.4.8-pre3 NTFS update (1.1.16) Anton Altaparmakov
@ 2001-08-01 10:40   ` Urban Widmark
  2001-08-01 18:21   ` Anton Altaparmakov
  1 sibling, 0 replies; 3+ messages in thread
From: Urban Widmark @ 2001-08-01 10:40 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: linux-kernel

On Wed, 1 Aug 2001, Anton Altaparmakov wrote:

> - Simplified time conversion functions drastically without
> sacrificing accuracy, now the offending function is 3 lines instead of
> two pages of code. (-8

Does this mean I have to change the code I borrowed?
(Never mind ... :)


> -/* Converts a single wide character to a sequence of utf8 bytes.
> +/*
> + * Converts a single wide character to a sequence of utf8 bytes.
>   * The character is represented in host byte order.
> - * Returns the number of bytes, or 0 on error. */
> -static int to_utf8(ntfs_u16 c, unsigned char* buf)
> + * Returns the number of bytes, or 0 on error.
> + */
> +static int to_utf8(ntfs_u16 c, unsigned char *buf)

How is this different from utf8_wctomb in fs/nls/nls_base.c?
(in purpose)


If it is to allow ntfs_dupuni2utf8 to count the new string length, could
that be done differently? If there is a max allowed length of filenames
the "double parsing" can be avoided.

ntfs_printcb -> ntfs_encodeuni -> ntfs_dupuni2utf8 -> to_utf8

ntfs_dupuni2utf8 does a kmalloc, which is later free'd by ntfs_printcb.
Which in turn is called once for each entry read by ntfs_readdir.

Wouldn't it be nicer to allocate one 255*max_utf8_size buffer in
ntfs_readdir and use that for all entries. Assuming 255 is the upper limit
on NTFS filename length, as I read somewhere.


smbfs does something like this, except it allocates a buffer at mount time
(which works since it is only used while protected by a per-mount lock).

/Urban


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] 2.4.8-pre3 NTFS update (1.1.16)
  2001-08-01  3:51 ` [PATCH] 2.4.8-pre3 NTFS update (1.1.16) Anton Altaparmakov
  2001-08-01 10:40   ` Urban Widmark
@ 2001-08-01 18:21   ` Anton Altaparmakov
  1 sibling, 0 replies; 3+ messages in thread
From: Anton Altaparmakov @ 2001-08-01 18:21 UTC (permalink / raw)
  To: Urban Widmark; +Cc: linux-kernel

Hi Urban,

At 11:40 01/08/2001, Urban Widmark wrote:
>On Wed, 1 Aug 2001, Anton Altaparmakov wrote:
> > - Simplified time conversion functions drastically without
> > sacrificing accuracy, now the offending function is 3 lines instead of
> > two pages of code. (-8
>
>Does this mean I have to change the code I borrowed?
>(Never mind ... :)

You don't _have_ to, but it will remove some nasty code and speed up the 
conversion significantly. I haven't benchmarked it but I can imagine the 
speed up is several fold... (-:

> > +static int to_utf8(ntfs_u16 c, unsigned char *buf)
>
>How is this different from utf8_wctomb in fs/nls/nls_base.c?
>(in purpose)
>
>If it is to allow ntfs_dupuni2utf8 to count the new string length, could
>that be done differently? If there is a max allowed length of filenames
>the "double parsing" can be avoided.

Possibly no difference. I didn't touch this much. You are of course right 
that it can be optimized a lot. The double parsing stroke me as odd, too 
but considering it works, I left it as is for the moment. This patch was a 
"fix it" rather than a "make it fly" one. (-;

The reason for leaving the utf8 built in code was to allow people without 
nls_utf8.o compiled into the kernel / present as a module to be able to use 
utf8 anyway. - It is the only way I can see to get some extended characters 
to work. - The driver now notifies the user via printk(KERN_ERR ...); if it 
finds something and cannot convert it and suggests to the user to use the 
utf8 mount option to be able to access the files. - This is as easy as 
doing a remount -o remount,utf8 of the file system so it is quite nice IMO.

In the future this could allow NTFS to be compiled without NLS support 
being built into the kernel (at the moment NTFS requires NLS but that could 
be changed). - Alternatively, we could just get rid of this altogether and 
tell the user to use iocharset=utf8 and if they don't have it, tough...

>ntfs_printcb -> ntfs_encodeuni -> ntfs_dupuni2utf8 -> to_utf8
>
>ntfs_dupuni2utf8 does a kmalloc, which is later free'd by ntfs_printcb.
>Which in turn is called once for each entry read by ntfs_readdir.
>
>Wouldn't it be nicer to allocate one 255*max_utf8_size buffer in
>ntfs_readdir and use that for all entries. Assuming 255 is the upper limit
>on NTFS filename length, as I read somewhere.

Yes this would be a good optimization, indeed.

>smbfs does something like this, except it allocates a buffer at mount time
>(which works since it is only used while protected by a per-mount lock).

<looks at code>Interesting. I am not sure NTFS will use that kind of lock 
so I would rather not go that far (or at least I would prefer to use an 
rwsemaphore rather than a straight semaphore, which precludes using only 
one buffer per mount). But I will keep it in mind.

Thanks for reviewing the code.

Best regards,

Anton


-- 
   "Nothing succeeds like success." - Alexandre Dumas
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Linux NTFS Maintainer / WWW: http://linux-ntfs.sf.net/
ICQ: 8561279 / WWW: http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-08-01 18:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <Pine.LNX.4.30.0108011135300.9860-100000@cola.teststation.c om>
2001-08-01  3:51 ` [PATCH] 2.4.8-pre3 NTFS update (1.1.16) Anton Altaparmakov
2001-08-01 10:40   ` Urban Widmark
2001-08-01 18:21   ` Anton Altaparmakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).