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