JFS: mount option iocharset=none
Linux Kernel Mailing List <[email protected]> Fri, 18 Feb 2005 21:44:47 +0000
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
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. */