ChangeSet 1.1543, 2005/02/18 15:44:47-06:00, [EMAIL PROTECTED]

        JFS: mount option iocharset=none
        
        This enables bytes in a filename to be stored directly, rather than
        doing character translation by charset.  This allows compatibility
        with the 2.6 kernel's default behavior, without changing the default
        in the 2.4 kernel.
        
        Signed-off-by: Dave Kleikamp <[EMAIL PROTECTED]>



 Documentation/filesystems/jfs.txt |    3 +
 fs/jfs/jfs_unicode.c              |   72 ++++++++++++++++++++++++++------------
 fs/jfs/jfs_unicode.h              |    7 +--
 fs/jfs/namei.c                    |   24 +++++-------
 fs/jfs/super.c                    |   31 ++++++++--------
 5 files changed, 83 insertions(+), 54 deletions(-)


diff -Nru a/Documentation/filesystems/jfs.txt 
b/Documentation/filesystems/jfs.txt
--- a/Documentation/filesystems/jfs.txt 2005-02-23 10:06:26 -08:00
+++ b/Documentation/filesystems/jfs.txt 2005-02-23 10:06:26 -08:00
@@ -15,7 +15,8 @@
                ASCII.  The default is compiled into the kernel as
                CONFIG_NLS_DEFAULT.  Use iocharset=utf8 for UTF8
                translations.  This requires CONFIG_NLS_UTF8 to be set
-               in the kernel .config file.
+               in the kernel .config file.  Specify iocharset=none for
+               no conversion (default linux-2.6 behavior).
 
 resize=value   Resize the volume to <value> blocks.  JFS only supports
                growing a volume, not shrinking it.  This option is only
diff -Nru a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
--- a/fs/jfs/jfs_unicode.c      2005-02-23 10:06:26 -08:00
+++ b/fs/jfs/jfs_unicode.c      2005-02-23 10:06:26 -08:00
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2005
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 #include <linux/fs.h>
 #include <linux/slab.h>
-#include "jfs_types.h"
+#include "jfs_incore.h"
 #include "jfs_filsys.h"
 #include "jfs_unicode.h"
 #include "jfs_debug.h"
@@ -34,17 +34,40 @@
 {
        int i;
        int outlen = 0;
+       static int warn_again = 5;      /* Only warn up to 5 times total */
+       int warn = !!warn_again;        /* once per string */
 
-       for (i = 0; (i < len) && from[i]; i++) {
-               int charlen;
-               charlen =
-                   codepage->uni2char(le16_to_cpu(from[i]), &to[outlen],
-                                      NLS_MAX_CHARSET_SIZE);
-               if (charlen > 0) {
-                       outlen += charlen;
-               } else {
-                       to[outlen++] = '?';
+       if (codepage) {
+               for (i = 0; (i < len) && from[i]; i++) {
+                       int charlen;
+                       charlen =
+                           codepage->uni2char(le16_to_cpu(from[i]),
+                                              &to[outlen],
+                                              NLS_MAX_CHARSET_SIZE);
+                       if (charlen > 0)
+                               outlen += charlen;
+                       else
+                               to[outlen++] = '?';
                }
+       } else {
+               for (i = 0; (i < len) && from[i]; i++) {
+                       if (le16_to_cpu(from[i]) & 0xff00) {
+                               if (warn) {
+                                       warn--;
+                                       warn_again--;
+                                       printk(KERN_ERR
+                       "non-latin1 character 0x%x found in JFS file name\n", 
+                                              le16_to_cpu(from[i]));
+                                       printk(KERN_ERR
+                               "mount with iocharset=utf8 to access\n");
+                               }
+                               to[i] = '?';
+                       }
+                       else
+                               to[i] = (char) (le16_to_cpu(from[i]));
+               }
+               outlen = i;
+
        }
        to[outlen] = 0;
        return outlen;
@@ -56,20 +79,27 @@
  * FUNCTION:   Convert character string to unicode string
  *
  */
-static int jfs_strtoUCS(wchar_t * to, const char *from, int len,
+static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len,
                struct nls_table *codepage)
 {
        int charlen;
        int i;
 
-       for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
-               charlen = codepage->char2uni(from, len, &to[i]);
-               if (charlen < 1) {
-                       jfs_err("jfs_strtoUCS: char2uni returned %d.", charlen);
-                       jfs_err("charset = %s, char = 0x%x",
-                               codepage->charset, (unsigned char) *from);
-                       return charlen;
+       if (codepage) {
+               for (i = 0; len && *from; i++, from += charlen, len -= charlen)
+               {
+                       charlen = codepage->char2uni(from, len, &to[i]);
+                       if (charlen < 1) {
+                               jfs_err("jfs_strtoUCS: char2uni returned %d.",
+                                       charlen);
+                               jfs_err("charset = %s, char = 0x%x",
+                                       codepage->charset, *from);
+                               return charlen;
+                       }
                }
+       } else {
+               for (i = 0; (i < len) && from[i]; i++)
+                       to[i] = (wchar_t) from[i];
        }
 
        to[i] = 0;
@@ -82,9 +112,9 @@
  * FUNCTION:   Allocate and translate to unicode string
  *
  */
-int get_UCSname(struct component_name * uniName, struct dentry *dentry,
-               struct nls_table *nls_tab)
+int get_UCSname(struct component_name * uniName, struct dentry *dentry)
 {
+       struct nls_table *nls_tab = JFS_SBI(dentry->d_sb)->nls_tab;
        int length = dentry->d_name.len;
 
        if (length > JFS_NAME_MAX)
diff -Nru a/fs/jfs/jfs_unicode.h b/fs/jfs/jfs_unicode.h
--- a/fs/jfs/jfs_unicode.h      2005-02-23 10:06:26 -08:00
+++ b/fs/jfs/jfs_unicode.h      2005-02-23 10:06:26 -08:00
@@ -1,6 +1,6 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -30,8 +30,7 @@
 
 extern signed char UniUpperTable[512];
 extern UNICASERANGE UniUpperRange[];
-extern int get_UCSname(struct component_name *, struct dentry *,
-                      struct nls_table *);
+extern int get_UCSname(struct component_name *, struct dentry *);
 extern int jfs_strfromUCS_le(char *, const wchar_t *, int, struct nls_table *);
 
 #define free_UCSname(COMP) kfree((COMP)->name)
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c    2005-02-23 10:06:25 -08:00
+++ b/fs/jfs/namei.c    2005-02-23 10:06:25 -08:00
@@ -74,7 +74,7 @@
         * search parent directory for entry/freespace
         * (dtSearch() returns parent directory page pinned)
         */
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out1;
 
        /*
@@ -195,7 +195,7 @@
         * search parent directory for entry/freespace
         * (dtSearch() returns parent directory page pinned)
         */
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out1;
 
        /*
@@ -318,9 +318,8 @@
                goto out;
        }
 
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) {
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out;
-       }
 
        tid = txBegin(dip->i_sb, 0);
 
@@ -437,7 +436,7 @@
 
        jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name);
 
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out;
 
        IWRITE_LOCK(ip);
@@ -780,7 +779,7 @@
        /*
         * scan parent directory for entry/freespace
         */
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(ip->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out;
 
        if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
@@ -865,7 +864,7 @@
         * (dtSearch() returns parent directory page pinned)
         */
 
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out1;
 
        /*
@@ -1044,12 +1043,10 @@
        old_ip = old_dentry->d_inode;
        new_ip = new_dentry->d_inode;
 
-       if ((rc = get_UCSname(&old_dname, old_dentry,
-                             JFS_SBI(old_dir->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&old_dname, old_dentry)))
                goto out1;
 
-       if ((rc = get_UCSname(&new_dname, new_dentry,
-                             JFS_SBI(old_dir->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&new_dname, new_dentry)))
                goto out2;
 
        /*
@@ -1301,7 +1298,7 @@
 
        jfs_info("jfs_mknod: %s", dentry->d_name.name);
 
-       if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
+       if ((rc = get_UCSname(&dname, dentry)))
                goto out;
 
        ip = ialloc(dir, mode);
@@ -1376,8 +1373,7 @@
        else if (strcmp(name, "..") == 0)
                inum = PARENT(dip);
        else {
-               if ((rc =
-                    get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+               if ((rc = get_UCSname(&key, dentry)))
                        return ERR_PTR(rc);
                rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
                free_UCSname(&key);
diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c    2005-02-23 10:06:26 -08:00
+++ b/fs/jfs/super.c    2005-02-23 10:06:26 -08:00
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) International Business Machines Corp., 2000-2003
+ *   Copyright (C) International Business Machines Corp., 2000-2005
  *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   This program is free software;  you can redistribute it and/or modify
@@ -155,8 +155,10 @@
        rc = jfs_umount(sb);
        if (rc)
                jfs_err("jfs_umount failed with return code %d", rc);
-       unload_nls(sbi->nls_tab);
-       sbi->nls_tab = NULL;
+       if (sbi->nls_tab) {
+               unload_nls(sbi->nls_tab);
+               sbi->nls_tab = NULL;
+       }
 
        kfree(sbi);
 }
@@ -182,7 +184,7 @@
 static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
                         int *flag)
 {
-       void *nls_map = NULL;
+       void *nls_map = (void *)-1;     /* -1: no change;  NULL: none */
        char *this_char;
        char *value;
        struct jfs_sb_info *sbi = JFS_SBI(sb);
@@ -222,13 +224,12 @@
                } else if (!strcmp(this_char, "iocharset")) {
                        if (!value || !*value)
                                goto needs_arg;
-                       if (nls_map)    /* specified iocharset twice! */
+                       if (nls_map && nls_map != (void *) -1)
                                unload_nls(nls_map);
-                       nls_map = load_nls(value);
-                       if (!nls_map) {
-                               printk(KERN_ERR "JFS: charset not found\n");
-                               goto cleanup;
-                       }
+                       if (!strcmp(value, "none"))
+                               nls_map = NULL;
+                       else
+                               nls_map = load_nls(value);
                } else if (!strcmp(this_char, "resize")) {
                        if (!value || !*value) {
                                *newLVSize = jfs_get_volume_size(sb);
@@ -250,9 +251,9 @@
                        goto cleanup;
                }
        }
-       if (nls_map) {
+       if (nls_map != (void *) -1) {
                /* Discard old (if remount) */
-               if (sbi->nls_tab)
+               if (sbi->nls_tab && sbi->nls_tab != (void *) -1)
                        unload_nls(sbi->nls_tab);
                sbi->nls_tab = nls_map;
        }
@@ -260,7 +261,7 @@
 needs_arg:
        printk(KERN_ERR "JFS: %s needs an argument\n", this_char);
 cleanup:
-       if (nls_map)
+       if (nls_map && nls_map != (void *) -1)
                unload_nls(nls_map);
        return 0;
 }
@@ -328,6 +329,8 @@
        /* initialize the mount flag and determine the default error handler */
        flag = JFS_ERR_REMOUNT_RO;
 
+       /* nls_tab will be set to NULL if no character mapping is requested */
+       sbi->nls_tab = (void *) -1;
        if (!parse_options((char *) data, sb, &newLVSize, &flag)) {
                kfree(sbi);
                return NULL;
@@ -378,7 +381,7 @@
        if (!sb->s_root)
                goto out_no_root;
 
-       if (!sbi->nls_tab)
+       if (sbi->nls_tab == (void *) -1)
                sbi->nls_tab = load_nls_default();
 
        /* logical blocks are represented by 40 bits in pxd_t, etc. */
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-24" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to