aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-09 02:57:09 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-09 02:57:09 -0700
commita5b62ecbd4a108e595f47a475e7a3acf5ca24f0b (patch)
tree14f0cb6d0799469c018edcc1f36fe6274b1f200a /fs
parentdcff0e756ca34d301e760ae751eaf285c81a5a51 (diff)
downloadhistory-a5b62ecbd4a108e595f47a475e7a3acf5ca24f0b.tar.gz
Revert FAT NLS changes.
It's causing massive user confusion, and breaks installers by mounting the filesystem read-only. Cset exclude: hirofumi@mail.parknet.co.jp[torvalds]|ChangeSet|20040802210150|02337
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig57
-rw-r--r--fs/fat/inode.c120
2 files changed, 103 insertions, 74 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 083ee1440ad25a..a4035fba9b18d6 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -554,6 +554,44 @@ menu "DOS/FAT/NT Filesystems"
config FAT_FS
tristate
select NLS
+ help
+ If you want to use one of the FAT-based file systems (the MS-DOS,
+ VFAT (Windows 95) and UMSDOS (used to run Linux on top of an
+ ordinary DOS partition) file systems), then you must say Y or M here
+ to include FAT support. You will then be able to mount partitions or
+ diskettes with FAT-based file systems and transparently access the
+ files on them, i.e. MSDOS files will look and behave just like all
+ other Unix files.
+
+ This FAT support is not a file system in itself, it only provides
+ the foundation for the other file systems. You will have to say Y or
+ M to at least one of "MSDOS fs support" or "VFAT fs support" in
+ order to make use of it.
+
+ Another way to read and write MSDOS floppies and hard drive
+ partitions from within Linux (but not transparently) is with the
+ mtools ("man mtools") program suite. You don't need to say Y here in
+ order to do that.
+
+ If you need to move large files on floppies between a DOS and a
+ Linux box, say Y here, mount the floppy under Linux with an MSDOS
+ file system and use GNU tar's M option. GNU tar is a program
+ available for Unix and DOS ("man tar" or "info tar").
+
+ It is now also becoming possible to read and write compressed FAT
+ file systems; read <file:Documentation/filesystems/fat_cvf.txt> for
+ details.
+
+ The FAT support will enlarge your kernel by about 37 KB. If unsure,
+ say Y.
+
+ To compile this as a module, choose M here: the module will be called
+ fat. Note that if you compile the FAT support as a module, you
+ cannot compile any of the FAT-based file systems into the kernel
+ -- they will have to be modules as well.
+ The file system of your root partition (the one containing the
+ directory /) cannot be a module, so don't say M here if you intend
+ to use UMSDOS as your root file system.
config MSDOS_FS
tristate "MSDOS fs support"
@@ -606,6 +644,25 @@ config VFAT_FS
To compile this as a module, choose M here: the module will be called
vfat.
+config FAT_DEFAULT_CODEPAGE
+ int "Default codepage for FAT"
+ depends on MSDOS_FS || VFAT_FS
+ default 437
+ help
+ This option should be set to the codepage of your FAT filesystems.
+ It can be overridden with the 'codepage' mount option.
+
+config FAT_DEFAULT_IOCHARSET
+ string "Default iocharset for FAT"
+ depends on VFAT_FS
+ default "iso8859-1"
+ help
+ Set this to the default I/O character set you'd like FAT to use.
+ It should probably match the character set that most of your
+ FAT filesystems use, and can be overridded with the 'iocharset'
+ mount option for FAT filesystems. Note that UTF8 is *not* a
+ supported charset for FAT filesystems.
+
config UMSDOS_FS
#dep_tristate ' UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
# UMSDOS is temprory broken
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index b4ee8c93e67f6a..c0fc6b7d6a9874 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -23,6 +23,14 @@
#include <linux/parser.h>
#include <asm/unaligned.h>
+#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
+/* if user don't select VFAT, this is undefined. */
+#define CONFIG_FAT_DEFAULT_IOCHARSET ""
+#endif
+
+static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
+static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
+
/*
* New FAT inode stuff. We do the following:
* a) i_ino is constant and has nothing with on-disk location.
@@ -166,15 +174,15 @@ void fat_put_super(struct super_block *sb)
if (sbi->nls_disk) {
unload_nls(sbi->nls_disk);
sbi->nls_disk = NULL;
- sbi->options.codepage = 0;
+ sbi->options.codepage = fat_default_codepage;
}
if (sbi->nls_io) {
unload_nls(sbi->nls_io);
sbi->nls_io = NULL;
}
- if (sbi->options.iocharset) {
+ if (sbi->options.iocharset != fat_default_iocharset) {
kfree(sbi->options.iocharset);
- sbi->options.iocharset = NULL;
+ sbi->options.iocharset = fat_default_iocharset;
}
sb->s_fs_info = NULL;
@@ -193,10 +201,11 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_printf(m, ",gid=%u", opts->fs_gid);
seq_printf(m, ",fmask=%04o", opts->fs_fmask);
seq_printf(m, ",dmask=%04o", opts->fs_dmask);
- if (sbi->nls_disk && opts->codepage)
+ if (sbi->nls_disk && opts->codepage != fat_default_codepage)
seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
if (isvfat) {
- if (sbi->nls_io && opts->iocharset)
+ if (sbi->nls_io &&
+ strcmp(opts->iocharset, fat_default_iocharset))
seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
switch (opts->shortname) {
@@ -327,14 +336,15 @@ static int parse_options(char *options, int is_vfat, int *debug,
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
+ char *iocharset;
opts->isvfat = is_vfat;
opts->fs_uid = current->uid;
opts->fs_gid = current->gid;
opts->fs_fmask = opts->fs_dmask = current->fs->umask;
- opts->codepage = 0;
- opts->iocharset = NULL;
+ opts->codepage = fat_default_codepage;
+ opts->iocharset = fat_default_iocharset;
if (is_vfat)
opts->shortname = VFAT_SFN_DISPLAY_LOWER|VFAT_SFN_CREATE_WIN95;
else
@@ -433,11 +443,12 @@ static int parse_options(char *options, int is_vfat, int *debug,
/* vfat specific */
case Opt_charset:
- if (opts->iocharset)
+ if (opts->iocharset != fat_default_iocharset)
kfree(opts->iocharset);
- opts->iocharset = match_strdup(&args[0]);
- if (opts->iocharset == NULL)
+ iocharset = match_strdup(&args[0]);
+ if (!iocharset)
return -ENOMEM;
+ opts->iocharset = iocharset;
break;
case Opt_shortname_lower:
opts->shortname = VFAT_SFN_DISPLAY_LOWER
@@ -486,9 +497,15 @@ static int parse_options(char *options, int is_vfat, int *debug,
return -EINVAL;
}
}
+ /* UTF8 doesn't provide FAT semantics */
+ if (!strcmp(opts->iocharset, "utf8")) {
+ printk(KERN_ERR "FAT: utf8 is not a recommended IO charset"
+ " for FAT filesystems, filesystem will be case sensitive!\n");
+ }
+
if (opts->unicode_xlate)
opts->utf8 = 0;
-
+
return 0;
}
@@ -768,66 +785,6 @@ static struct export_operations fat_export_ops = {
.get_parent = fat_get_parent,
};
-static int fat_load_nls(struct super_block *sb)
-{
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
- struct fat_mount_options *opts = &sbi->options;
- char codepage[50], *iocharset;
- int error = 0, not_specified = 0;
-
- if (opts->codepage)
- snprintf(codepage, sizeof(codepage), "cp%d", opts->codepage);
- else {
- not_specified = 1;
- strcpy(codepage, "default");
- }
- sbi->nls_disk = load_nls(codepage);
- if (sbi->nls_disk == NULL) {
- printk(KERN_ERR "FAT: codepage %s not found\n", codepage);
- error = -EINVAL;
- goto out;
- }
-
- if (opts->isvfat) {
- if (opts->iocharset)
- iocharset = opts->iocharset;
- else {
- not_specified = 1;
- iocharset = "default";
- }
- /*
- * FIXME: utf8 is using iocharset for upper/lower conversion
- * UTF8 doesn't provide FAT semantics
- */
- if (!strcmp(iocharset, "utf8")) {
- printk(KERN_WARNING
- "FAT: utf8 is not a recommended IO charset"
- " for FAT filesystem,"
- " filesystem will be case sensitive!\n");
- }
- sbi->nls_io = load_nls(iocharset);
- if (sbi->nls_io == NULL) {
- printk(KERN_ERR "FAT: IO charset %s not found\n",
- iocharset);
- error = -EINVAL;
- goto out;
- }
- }
-
- if (not_specified) {
- unsigned long not_ro = !(sb->s_flags & MS_RDONLY);
- if (not_ro)
- sb->s_flags |= MS_RDONLY;
-
- printk(KERN_INFO "FAT: %s option didn't specified\n"
- " File name can not access proper%s\n",
- opts->isvfat ? "codepage or iocharset" : "codepage",
- not_ro ? " (mounted as read-only)" : "");
- }
-out:
- return error;
-}
-
/*
* Read the super block of an MS-DOS FS.
*/
@@ -843,6 +800,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
int debug, first;
unsigned int media;
long error;
+ char buf[50];
sbi = kmalloc(sizeof(struct msdos_sb_info), GFP_KERNEL);
if (!sbi)
@@ -1057,9 +1015,23 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
goto out_invalid;
}
- error = fat_load_nls(sb);
- if (error)
+ error = -EINVAL;
+ sprintf(buf, "cp%d", sbi->options.codepage);
+ sbi->nls_disk = load_nls(buf);
+ if (!sbi->nls_disk) {
+ printk(KERN_ERR "FAT: codepage %s not found\n", buf);
goto out_fail;
+ }
+
+ /* FIXME: utf8 is using iocharset for upper/lower conversion */
+ if (sbi->options.isvfat) {
+ sbi->nls_io = load_nls(sbi->options.iocharset);
+ if (!sbi->nls_io) {
+ printk(KERN_ERR "FAT: IO charset %s not found\n",
+ sbi->options.iocharset);
+ goto out_fail;
+ }
+ }
error = -ENOMEM;
root_inode = new_inode(sb);
@@ -1093,7 +1065,7 @@ out_fail:
unload_nls(sbi->nls_io);
if (sbi->nls_disk)
unload_nls(sbi->nls_disk);
- if (sbi->options.iocharset)
+ if (sbi->options.iocharset != fat_default_iocharset)
kfree(sbi->options.iocharset);
sb->s_fs_info = NULL;
kfree(sbi);