I think you meant vfat, not msdos. I tried it under msdos, and it does
the correct thing. Under vfat, it showed the behavior you found. Here
is a patch that fixes it. I'm putting in some more work on this patch
because there are some bad interactions of the dcache and vfat short
aliases. Basically, if you do a lookup on a long name, remove a file
via the short alias, the long name doesn't get removed from the dcache.
For now, here is the patch.
- Gordon
diff -u linux{-2.1.75-clean,}/fs/vfat/namei.c
--- linux-2.1.75-clean/fs/vfat/namei.c Sun Dec 21 21:46:51 1997
+++ linux/fs/vfat/namei.c Mon Dec 29 01:58:27 1997
@@ -173,6 +173,9 @@
len = qstr->len;
name = qstr->name;
+ while (len && name[len-1] == '.')
+ len--;
+
hash = init_name_hash();
while (len--) {
c = tolower(*name++);
@@ -193,14 +196,12 @@
/* A filename cannot end in '.' or we treat it like it has none */
alen = a->len;
blen = b->len;
- if (alen != blen) {
- if (a->name[alen-1] == '.')
- alen--;
- if (b->name[blen-1] == '.')
- blen--;
- if (alen != blen)
- return 1;
- }
+ while (alen && a->name[alen-1] == '.')
+ alen--;
+ while (blen && b->name[blen-1] == '.')
+ blen--;
+ if (alen != blen)
+ return 1;
return strnicmp(a->name, b->name, alen);
}
@@ -940,11 +941,8 @@
vf->name, vf->len, name, name_len);
#endif
- /* Filenames cannot end in '.' or we treat like it has none */
if (vf->len != name_len) {
- if ((vf->len != name_len + 1) || (vf->name[name_len] != '.')) {
- return 0;
- }
+ return 0;
}
s1 = name; s2 = vf->name;
@@ -1584,7 +1582,7 @@
/* Is this the same file, different case? */
if (new_inode != old_inode) {
PRINTK(("vfat_rename 9\n"));
- res = vfat_unlinkx(new_dir,new_dentry,1);
+ res = vfat_unlink(new_dir,new_dentry);
PRINTK(("vfat_rename 10\n"));
if (res < 0) goto rename_done;
}