From: OGAWA Hirofumi From Michal Rokos The problem is: even if vfat_striptail_len() counts len of name without trailing dots and sets len to the correct value, utf8_mbstowcs() doesn't care about len and takes whole name. So dirs and files with dots can be created on vfat fs. fs/nls/nls_base.c | 1 + fs/vfat/namei.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff -puN fs/nls/nls_base.c~fat-02-utf8-tailing-dots-fix fs/nls/nls_base.c --- 25/fs/nls/nls_base.c~fat-02-utf8-tailing-dots-fix 2003-12-21 22:17:59.000000000 -0800 +++ 25-akpm/fs/nls/nls_base.c 2003-12-21 22:17:59.000000000 -0800 @@ -99,6 +99,7 @@ utf8_mbstowcs(wchar_t *pwcs, const __u8 } } else { *op++ = *ip++; + n--; } } return (op - pwcs); diff -puN fs/vfat/namei.c~fat-02-utf8-tailing-dots-fix fs/vfat/namei.c --- 25/fs/vfat/namei.c~fat-02-utf8-tailing-dots-fix 2003-12-21 22:17:59.000000000 -0800 +++ 25-akpm/fs/vfat/namei.c 2003-12-21 22:17:59.000000000 -0800 @@ -573,13 +573,18 @@ xlate_to_uni(const unsigned char *name, int charlen; if (utf8) { + int name_len = strlen(name); + *outlen = utf8_mbstowcs((wchar_t *)outname, name, PAGE_SIZE); - if (name[len-1] == '.') - *outlen-=2; + + /* + * We stripped '.'s before and set len appropriately, + * but utf8_mbstowcs doesn't care about len + */ + *outlen -= (name_len-len); + op = &outname[*outlen * sizeof(wchar_t)]; } else { - if (name[len-1] == '.') - len--; if (nls) { for (i = 0, ip = name, op = outname, *outlen = 0; i < len && *outlen <= 260; *outlen += 1) _