This patch originated with "H. Kawaguchi" <[EMAIL PROTECTED]>, but I've tweaked it somewhat. It's seen fairly heavy use since. ---------------------------------------------------------------------- Hi, I think that a file name generation rule on VFAT is different from Windows. Long name is not generated when I make 8+3 file name in capital letters on Windows. But Linux generates it. This patch does the following revisions. o It makes a file name generation rule same as Windows o By default, it shows short name in capital letters o By "small" option, it shows short name with small letters o By "forcelong" option, it always generates long name ---------------------------------------------------------------------- Index: include/linux/msdos_fs_sb.h --- include/linux/msdos_fs_sb.h.prev +++ include/linux/msdos_fs_sb.h Sat Jun 17 17:48:32 2000 @@ -25,5 +25,7 @@ numtail:1, /* Does first alias have a numeric '~1' type tail? */ atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */ - fat32:1; /* Is this a FAT32 partition? */ + fat32:1, /* Is this a FAT32 partition? */ + small_letter:1, /* Use small letters for short name */ + force_long:1; /* Force create longname */ }; Index: fs/fat/dir.c --- fs/fat/dir.c.prev +++ fs/fat/dir.c Sat Jun 17 17:48:32 2000 @@ -140,4 +140,5 @@ int fat_search_long( int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate; int utf8 = MSDOS_SB(sb)->options.utf8; + int small_letter = MSDOS_SB(sb)->options.small_letter; unsigned char *unicode = NULL; struct nls_table *nls = MSDOS_SB(sb)->nls_io; @@ -227,5 +228,5 @@ parse_long: for (i = 0, last = 0; i < 8;) { if (!(c = de->name[i])) break; - if (c >= 'A' && c <= 'Z') c += 32; + if (small_letter) c = tolower(c); if (c == 0x05) c = 0xE5; if ((bufname[i++] = c) != ' ') @@ -236,5 +237,5 @@ parse_long: for (i2 = 0; i2 < 3; i2++) { if (!(c = de->ext[i2])) break; - if (c >= 'A' && c <= 'Z') c += 32; + if (small_letter) c = tolower(c); if ((bufname[i++] = c) != ' ') last = i; @@ -302,4 +303,5 @@ static int fat_readdirx( int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate; int utf8 = MSDOS_SB(sb)->options.utf8; + int small_letter = MSDOS_SB(sb)->options.small_letter; unsigned char *unicode = NULL; struct nls_table *nls = MSDOS_SB(sb)->nls_io; @@ -420,5 +422,5 @@ ParseLong: for (i = 0, last = 0; i < 8;) { if (!(c = de->name[i])) break; - if (c >= 'A' && c <= 'Z') c += 32; + if (small_letter) c = tolower(c); /* see namei.c, msdos_format_name */ if (c == 0x05) c = 0xE5; @@ -430,5 +432,5 @@ ParseLong: for (i2 = 0; i2 < 3; i2++) { if (!(c = de->ext[i2])) break; - if (c >= 'A' && c <= 'Z') c += 32; + if (small_letter) c = tolower(c); if ((ptname[i++] = c) != ' ') last = i; Index: fs/fat/inode.c --- fs/fat/inode.c.prev +++ fs/fat/inode.c Sat Jun 17 17:48:32 2000 @@ -217,4 +217,5 @@ static int parse_options(char *options,i opts->codepage = 0; opts->utf8 = 0; + opts->small_letter = 0; opts->iocharset = NULL; *debug = *fat = 0; @@ -261,4 +262,7 @@ static int parse_options(char *options,i else if (!strcmp(this_char,"showexec")) { opts->showexec = 1; + } + else if (!strcmp(this_char,"small")) { + opts->small_letter = 1; } else if (!strcmp(this_char,"dotsOK") && value) { Index: fs/vfat/namei.c --- fs/vfat/namei.c.prev +++ fs/vfat/namei.c Sat Jun 17 17:48:32 2000 @@ -121,4 +121,5 @@ static int parse_options(char *options, opts->numtail = 1; opts->utf8 = 0; + opts->force_long = 0; if (!options) return 1; @@ -143,7 +144,8 @@ static int parse_options(char *options, } else if (!strcmp(this_char,"nonumtail")) { ret = simple_getbool(value, &val); - if (ret) { - opts->numtail = !val; - } + if (ret) opts->numtail = !val; + } else if (!strcmp(this_char,"forcelong") || + !strcmp(this_char,"force_long")) { + opts->force_long = 1; } if (this_char != options) @@ -384,5 +386,5 @@ static int vfat_valid_shortname(const ch if (utf8 && (c & 0x80)) return -EINVAL; if (strchr(replace_chars,c)) return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; + if (islower(c)) return -EINVAL; if (c < ' '|| c==':') return -EINVAL; if (c == '.') break; @@ -407,5 +409,5 @@ static int vfat_valid_shortname(const ch if (c < ' ' || c == '.'|| c==':') return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; + if (islower(c)) return -EINVAL; space = c == ' '; } @@ -429,4 +431,14 @@ static int vfat_find_form(struct inode * } +static void vfat_format_name_fast(const char *name,int len,char *res) +{ + char *walk = res; + + while (len-- && *name != '.') *walk++ = *name++; + while (walk-res < 8) *walk++ = ' '; + while (--len >= 0) *walk++ = *++name; + while (walk-res < MSDOS_NAME) *walk++ = ' '; +} + static int vfat_format_name(const char *name,int len,char *res,int utf8) { @@ -440,8 +452,8 @@ static int vfat_format_name(const char * if (utf8 && (c & 0x80)) return -EINVAL; if (strchr(replace_chars,c)) return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; + if (islower(c)) return -EINVAL; if (c < ' '|| c==':') return -EINVAL; space = c == ' '; - *walk = c >= 'a' && c <= 'z' ? c-32 : c; + *walk = c; } if (space) return -EINVAL; @@ -456,7 +468,7 @@ static int vfat_format_name(const char * if (c < ' ' || c == '.'|| c==':') return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; + if (islower(c)) return -EINVAL; space = c == ' '; - *walk++ = c >= 'a' && c <= 'z' ? c-32 : c; + *walk++ = c; } if (space) return -EINVAL; @@ -506,9 +518,5 @@ static int vfat_create_shortname(struct if (*ip == ' ') break; - if (*ip >= 'A' && *ip <= 'Z') { - *p = *ip + 32; - } else { - *p = *ip; - } + *p = toupper(*ip); } } @@ -556,9 +564,5 @@ static int vfat_create_shortname(struct baselen++; } else if (!strchr(skip_chars, *ip)) { - if (*ip >= 'a' && *ip <= 'z') { - *p = *ip - 32; - } else { - *p = *ip; - } + *p = toupper(*ip); if (strchr(replace_chars, *p)) *p='_'; p++; baselen++; @@ -577,9 +581,5 @@ static int vfat_create_shortname(struct extlen++; } else if (!strchr(skip_chars, *ip)) { - if (*ip >= 'a' && *ip <= 'z') { - *p = *ip - 32; - } else { - *p = *ip; - } + *p = toupper(*ip); if (strchr(replace_chars, *p)) *p='_'; extlen++; @@ -775,5 +775,5 @@ static int vfat_build_slots(struct inode struct msdos_dir_entry *de; char msdos_name[MSDOS_NAME]; - int res, xlate, utf8; + int res, xlate, utf8, force_long; struct nls_table *nls; @@ -781,17 +781,22 @@ static int vfat_build_slots(struct inode xlate = MSDOS_SB(dir->i_sb)->options.unicode_xlate; utf8 = MSDOS_SB(dir->i_sb)->options.utf8; + force_long = MSDOS_SB(dir->i_sb)->options.force_long; nls = MSDOS_SB(dir->i_sb)->nls_io; *slots = 1; - res = vfat_valid_longname(name, len, xlate); - if (res < 0) - return res; if (vfat_valid_shortname(name, len, utf8) >= 0) { - vfat_format_name(name, len, de->name, utf8); - return 0; + if (!force_long) { + vfat_format_name_fast(name, len, de->name); + return 0; + } + vfat_format_name_fast(name, len, msdos_name); + } else { + res = vfat_valid_longname(name, len, xlate); + if (res < 0) + return res; + res = vfat_create_shortname(dir, name, len, msdos_name, utf8); + if (res < 0) + return res; } - res = vfat_create_shortname(dir, name, len, msdos_name, utf8); - if (res < 0) - return res; return vfat_fill_long_slots(ds, name, len, msdos_name, slots, xlate, utf8, nls); -- Chip Salzenberg - a.k.a. - <[EMAIL PROTECTED]> "I wanted to play hopscotch with the impenetrable mystery of existence, but he stepped in a wormhole and had to go in early." // MST3K - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/