I think I found a bug in VFAT filesystem.
I wrote to maintainer (Gordon Chaffee, chaffee@cs.berkeley.edu)
a week ago and there were no reply. Maybe he's on vacation,
I don't know. So I'm posting my message to
linux-kernel@vger.rutgers.edu
If it's wrong place to discuss such matters, please tell me so
[and direct to the right place!]
Since I am new to Linux and Unix in general, I will not try
to write patches. I'll just describe what I have seen.
I use RedHat Linux, my kernel version is 2.2.5.
I needed to work with filenames with Cyrillic letters.
When I copied some files from VFAT to Linux partition (ext2 fs)
and back, some of them become inaccessible. Win95 sees them
but cannot access. It says "Access denied. File was deleted
or renamed".
Some observation with disk editor showed that Cyrillic shortnames
wasn't in upper case. I presume you aren't willing to
install Cyrillic support to your system just in order to read
my example, so let's imagine filenames in my example aren't in
Latin but in Cyrillic. Maybe you can duplicate example with
accented Latin chars:
<< Stripped and commented output of DIR execd in DOS box >>
Shortnam Ext Long name.ext My comment
-------- --- ------------- ----------
ABV ABV no conversion at all. ok
ABV123~1 ABV123456789 upcase longname -> upcase shortname. ok
GdE GdE mixed case longname -> mixed case shortname. BAD
GdE123~1 GdE123456789 mixed case longname -> mixed case shortname. BAD
gzi gzi locase longname -> locase shortname. BAD
gzi123~1 gzi123456789 locase longname -> locase shortname. BAD
GdE and gzi cannot be accessed (opened) by Win95, DOS box and clean DOS.
GdE123456789 and gzi123456789 can be accessed by Win95, but not
by DOS box and clean DOS. When shortnames are fixed to GDE, GDE123~1,
GZI, GZI123~1 via disk editor they become accessible but longnames are
lost (shortname checksum error). Alternatively they can be fixed by
moving them to another dir and back in Win95 Explorer.
Where to fix VFAT sources:
We need more general (Unicode-aware?) strnicmp() ant toupper() in
linux/fs/vfat/namei.c:
............
static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b)
{
....
if (alen == blen) {
if (strnicmp(a->name, b->name, alen) == 0) <- strnicmp isn't adequate
return 0;
}
............
static int vfat_create_shortname(struct inode *dir, const char *name,
int len, char *name_res, int utf8)
{
....
if (*ip >= 'a' && *ip <= 'z') {
*p = *ip - 32; <- primitive "toupper"
....
if (*ip >= 'a' && *ip <= 'z') { <- here is another
*p = *ip - 32; <- "toupper"
............
and maybe some other places also.... I don't know...
Maybe we should use MSDOS_SB(dentry->d_sb)->... and MSDOS_SB(dir->i_sb)->...
...->nls_io/nls_disk (struct nls_table*)
...->options.codepage (ushort)
...->options.iocharset (char*)
to obtain codepage data and do
u=c_to_uni(c); u=uni_toupper(u); c = uni_to_c(u)
for each char c in filename in these places?
I'll be happy to test patches.
Have a nice day,
-- Denis Vlasenko Email: vda_unique@iname.com
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/