Bug ID 1081022
Summary VFAT mount option "iocharset=utf8" breaks filename case sensitivity
Classification openSUSE
Product openSUSE Tumbleweed
Version Current
Hardware x86-64
OS openSUSE Factory
Status NEW
Severity Normal
Priority P5 - None
Component Kernel
Assignee kernel-maintainers@forge.provo.novell.com
Reporter shundhammer@suse.com
QA Contact qa-bugs@suse.de
Found By ---
Blocker ---

Created attachment 760171 [details]
Sample shell session (layout not broken by Bugzilla)

I found this while investigating what mount options to use for bug #1080731:

When a VFAT filesystem is mounted with option "iocharset=utf8", case
sensitivity in file/directory names changes its behaviour in weird ways: "mkdir
-p" can fail with EEXIST ("mkdir: cannot create directory ���/mnt/efi���: File
exists") which according to the mkdir man page should never happen.

Using mount option "utf8" instead which should be the same according to the
"mount" man page changes the behaviour to normal.

For one thing, "mkdir -p" should never fail with EEXIST. But that's a matter of
that tool which might do the check if a directory already exists the wrong way.
That's not what this bug is all about.

The weird behaviour is that this check behaves inconsistently depending on the
mount options used: "iocharset=utf8" should not change the way at all that a
purely ASCII file/directory name is treated. There are no non-ASCII characters
involved at all.

And there appears to be a difference if a VFAT "long name" exists or not: If
there is only a "short name" (the old MS-DOS 8+3 filename), the bug appears. If
there is also a "long name", everything works fine.


In addition to that, the promise that mount option "utf8" is equivalent to
"iocharset=utf8" is broken: Obviously, they behave differently.


Sample shell session (also attached):

[root @ morgul] ~ # uname -a
Linux morgul 4.14.9-1-default #1 SMP PREEMPT Mon Dec 25 15:42:48 UTC 2017
(9423ca2) x86_64 x86_64 x86_64 GNU/Linux

#
# Using iocharset=utf8
#
# FAIL
#

[root @ morgul] ~ # mkfs.vfat /dev/sdb1                                     
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o iocharset=utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
mkdir: cannot create directory ���/mnt/efi���: File exists
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
mkdir: cannot create directory ���/mnt/efi���: File exists
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o iocharset=utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro
0 0
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # umount /dev/sdb1

#
# Using default mount options (i.e. implicitly iocharset=iso8859-1)
#
# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1   
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat /dev/sdb1 /mnt                  
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1   
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1

#
# Using iocharset=iso8859-15
#
# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1   
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o iocharset=iso8859-15 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=iso8859-15,shortname=mixed,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o iocharset=iso8859-15 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=iso8859-15,shortname=mixed,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1

#
# Using utf8 (which should be equivalent to iocharset=utf8)
#
# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1   
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


# Using utf8 and iocharset=utf8 combined
#
# FAIL
#

[root @ morgul] ~ # mkfs.vfat /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o utf8,iocharset=utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
mkdir: cannot create directory ���/mnt/efi���: File exists
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
mkdir: cannot create directory ���/mnt/efi���: File exists
[root @ morgul] ~ # umount /dev/sdb1


# OK

[root @ morgul] ~ # mkfs.vfat /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o utf8,iocharset=utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=utf8,shortname=mixed,utf8,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


# FAIL

[root @ morgul] ~ # mkfs.vfat /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
[root @ morgul] ~ # mount -t vfat -o iocharset=utf8,utf8 /dev/sdb1 /mnt
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/EFI/boot
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
mkdir: cannot create directory ���/mnt/efi���: File exists
[root @ morgul] ~ # mkdir -p /mnt/efi/boot
mkdir: cannot create directory ���/mnt/efi���: File exists
[root @ morgul] ~ # grep sdb /proc/mounts
/dev/sdb1 /mnt vfat
rw,relatime,fmask=0002,dmask=0002,allow_utime=0020,codepage=437,iocharset=utf8,shortname=mixed,utf8,errors=remount-ro
0 0
[root @ morgul] ~ # umount /dev/sdb1


You are receiving this mail because: