VFAT

使用 VFAT

要使用 vfat 文件系统,请使用文件系统类型 “vfat”。例如:

mount -t vfat /dev/fd0 /mnt

不需要特殊的磁盘格式化工具,如果你想在 Linux 中格式化,可以使用 “mkdosfs”。

VFAT 挂载选项

uid=###

设置此文件系统上所有文件的所有者。默认值为当前进程的 uid。

gid=###

设置此文件系统上所有文件的组。默认值为当前进程的 gid。

umask=###

权限掩码(用于文件和目录,请参阅 umask(1))。默认值为当前进程的 umask。

dmask=###

目录的权限掩码。默认值为当前进程的 umask。

fmask=###

文件的权限掩码。默认值为当前进程的 umask。

allow_utime=###

此选项控制 mtime/atime 的权限检查。

-20:如果当前进程位于文件组 ID 的组中,则可以更改时间戳。

-2:其他用户可以更改时间戳。

默认值从 dmask 选项设置。如果目录可写,则 utime(2) 也被允许。即 ~dmask & 022。

通常,utime(2) 检查当前进程是否为文件的所有者,或者它是否具有 CAP_FOWNER 功能。但是 FAT 文件系统在磁盘上没有 uid/gid,因此正常的检查过于死板。使用此选项,您可以放松它。

codepage=###

设置代码页编号,用于在 FAT 文件系统上转换为短文件名字符。默认情况下,使用 FAT_DEFAULT_CODEPAGE 设置。

iocharset=<name>

字符集,用于用户可见文件名和 16 位 Unicode 字符之间的转换。长文件名以 Unicode 格式存储在磁盘上,但 Unix 在很大程度上不知道如何处理 Unicode。默认情况下,使用 FAT_DEFAULT_IOCHARSET 设置。

还可以选择使用 utf8 选项进行 UTF-8 转换。

注意

iocharset=utf8 不推荐使用。如果不确定,您应该考虑使用 utf8 选项。

utf8=<bool>

UTF-8 是控制台使用的 Unicode 文件系统安全版本。可以使用此选项为文件系统启用或禁用它。如果设置了 “uni_xlate”,则 UTF-8 将被禁用。默认情况下,使用 FAT_DEFAULT_UTF8 设置。

uni_xlate=<bool>

将未处理的 Unicode 字符转换为特殊的转义序列。这将允许您备份和还原使用任何 Unicode 字符创建的文件名。在 Linux 真正支持 Unicode 之前,这为您提供了一种替代方案。如果没有此选项,则在无法进行转换时使用 “?”。转义字符是 “:”,因为它在 vfat 文件系统上是非法的。使用的转义序列是 “:” 和十六进制 Unicode 的四位数字。

nonumtail=<bool>

创建 8.3 别名时,通常别名将以 “~1” 或波浪线后跟某个数字结尾。如果设置了此选项,则如果文件名为 “longfilename.txt” 并且目录中当前不存在 “longfile.txt”,则 longfile.txt 将是短别名,而不是 longfi~1.txt。

usefree

使用存储在 FSINFO 上的“空闲簇”值。它将用于确定空闲簇的数量,而无需扫描磁盘。但默认情况下不使用它,因为最近的 Windows 在某些情况下无法正确更新它。如果您确定 FSINFO 上的“空闲簇”是正确的,则可以通过此选项避免扫描磁盘。

quiet

停止打印某些警告消息。

check=s|r|n

大小写敏感性检查设置。

s:严格,区分大小写

r:宽松,不区分大小写

n:正常,默认设置,目前不区分大小写

nocase

此选项已弃用,请用于 vfat。请改用 shortname=win95

shortname=lower|win95|winnt|mixed

短文件名显示/创建设置。

lower:转换为小写以进行显示,模拟 Windows 95 的创建规则。

win95:模拟 Windows 95 的显示/创建规则。

winnt:模拟 Windows NT 的显示/创建规则。

mixed:模拟 Windows NT 的显示规则,模拟 Windows 95 的创建规则。

默认设置为 mixed

tz=UTC

将时间戳解释为 UTC 而不是本地时间。此选项禁用本地时间(Windows 在 FAT 上使用)和 UTC(Linux 在内部使用)之间的时间戳转换。这在挂载设置为 UTC 的设备(如数码相机)时特别有用,以避免本地时间的陷阱。

time_offset=minutes

设置用于将 FAT 使用的本地时间转换为 UTC 的时间戳偏移量。即,将从每个时间戳中减去 <minutes> 分钟,以将其转换为 Linux 内部使用的 UTC。当 sys_tz 中设置的时区不是文件系统使用的时区时,此选项很有用。请注意,即使存在 DST,此选项仍然无法在所有情况下提供正确的时间戳 - 不同 DST 设置中的时间戳将相差一小时。

showexec

如果设置,则仅当名称的扩展部分为 .EXE、.COM 或 .BAT 时,才允许文件的执行权限位。默认情况下未设置。

debug

可以设置,但当前实现未使用。

sys_immutable

如果设置,则 FAT 上的 ATTR_SYS 属性将作为 Linux 上的 IMMUTABLE 标志处理。默认情况下未设置。

flush

如果设置,文件系统将尝试比正常情况更早地刷新到磁盘。默认情况下未设置。

rodir

FAT 具有 ATTR_RO(只读)属性。在 Windows 上,目录的 ATTR_RO 将被忽略,并且仅由应用程序用作标志(例如,为自定义文件夹设置)。

如果您希望将 ATTR_RO 用作只读标志,即使对于目录也是如此,请设置此选项。

errors=panic|continue|remount-ro

指定 FAT 在发生严重错误时的行为:panic,继续不执行任何操作,或以只读模式重新挂载分区(默认行为)。

discard

如果设置,则在释放块时向块设备发出 discard/TRIM 命令。这对于 SSD 设备和稀疏/精简配置的 LUN 非常有用。

nfs=stale_rw|nostale_ro

仅当您要通过 NFS 导出 FAT 文件系统时才启用此功能。

stale_rw:此选项维护目录 inodes 的索引(缓存),该索引由 i_logstart 使用,供 nfs 相关代码用于改进查找。支持通过 NFS 的完整文件操作(读/写),但如果 NFS 服务器发生缓存驱逐,则可能导致 ESTALE 问题。

nostale_ro:此选项基于 MS-DOS 目录条目中文件的磁盘位置,设置 inode 编号和文件句柄。这确保了在文件从 inode 缓存中驱逐后不会返回 ESTALE。但是,这意味着重命名、创建和取消链接等操作可能会导致先前指向一个文件的文件句柄指向另一个文件,从而可能导致数据损坏。因此,此选项还会以只读方式挂载文件系统。

为了保持向后兼容性,也接受 '-o nfs',默认为 “stale_rw”。

dos1xfloppy <bool>: 0,1,yes,no,true,false

如果设置,请使用回退默认 BIOS 参数块配置,该配置由备份设备大小确定。这些静态参数与 DOS 1.x 为 160 kiB、180 kiB、320 kiB 和 360 kiB 软盘和软盘映像假定的默认值匹配。

限制

当使用 fallocate 与 FALLOC_FL_KEEP_SIZE 时,文件的 fallocated 区域在 umount/evict 时间被丢弃。因此,用户应假定如果存在内存压力导致从内存中驱逐 inode,则 fallocated 区域可以在最后关闭时被丢弃。因此,对于任何依赖于 fallocated 区域的用户,应确保在重新打开文件后重新检查 fallocate。

待办事项

需要摆脱原始扫描的东西。相反,始终使用获取下一个目录条目的方法。唯一剩下的使用原始扫描的是目录重命名代码。

可能的问题

  • vfat_valid_longname 没有正确检查保留名称。

  • 当卷名称与文件系统根目录中的目录名称相同时,目录名称有时会显示为空文件。

  • autoconv 选项无法正常工作。

测试套件

如果您计划对 vfat 文件系统进行任何修改,请获取 vfat 发行版附带的测试套件,网址为

http://web.archive.org/web/*/http://bmrc.berkeley.edu/people/chaffee/vfat.html

这将测试 vfat 文件系统的许多部分,并且欢迎对新功能或未经测试的功能进行额外测试。

关于 VFAT 文件系统结构的说明

本文档由 Galen C. Hunt gchunt@cs.rochester.edu 提供,并由 Gordon Chaffee 进行了轻微注释。

本文档对我所知的 Windows NT 3.5 和 Windows 95 中使用的扩展 FAT 文件系统进行了非常粗略的技术概述。我不保证以下任何内容是正确的,但似乎如此。

扩展 FAT 文件系统几乎与 DOS 版本中使用的 FAT 文件系统相同,包括 6.223410239847 :-)。 重要的变化是增加了长文件名。 这些名称最多支持 255 个字符,包括空格和大小写字符,而不是传统的 8.3 短名称。

以下是当前 Windows 95 文件系统中传统 FAT 条目的描述

struct directory { // Short 8.3 names
        unsigned char name[8];          // file name
        unsigned char ext[3];           // file extension
        unsigned char attr;             // attribute byte
        unsigned char lcase;            // Case for base and extension
        unsigned char ctime_ms;         // Creation time, milliseconds
        unsigned char ctime[2];         // Creation time
        unsigned char cdate[2];         // Creation date
        unsigned char adate[2];         // Last access date
        unsigned char reserved[2];      // reserved values (ignored)
        unsigned char time[2];          // time stamp
        unsigned char date[2];          // date stamp
        unsigned char start[2];         // starting cluster number
        unsigned char size[4];          // size of the file
};

lcase 字段指定 8.3 名称的基本名和/或扩展名是否应大写。 Windows 95 似乎没有使用此字段,但 Windows NT 使用了它。 文件名的大小写从 Windows NT 到 Windows 95 并不完全兼容。 但是,在相反的方向上并不完全兼容。 在 Windows NT 上写入的小写的 8.3 命名空间中的文件名将在 Windows 95 上显示为大写。

注意

请注意,startsize 值实际上是小端整数值。 此结构中字段的描述是众所周知的,可以在其他地方找到。

使用扩展 FAT 系统,Microsoft 为任何具有扩展名称的文件插入了额外的目录条目。 (任何合法地适合旧 8.3 编码方案的名称都没有额外的条目。)我将这些额外的条目称为插槽。 基本上,插槽是一种特殊格式的目录条目,最多可以容纳文件扩展名的 13 个字符。 将插槽视为与其对应的文件的目录条目的额外标签。 Microsoft 喜欢将文件的 8.3 条目称为其别名,并将扩展插槽目录条目称为文件名。

插槽目录条目的 C 结构如下

struct slot { // Up to 13 characters of a long name
        unsigned char id;               // sequence number for slot
        unsigned char name0_4[10];      // first 5 characters in name
        unsigned char attr;             // attribute byte
        unsigned char reserved;         // always 0
        unsigned char alias_checksum;   // checksum for 8.3 alias
        unsigned char name5_10[12];     // 6 more characters in name
        unsigned char start[2];         // starting cluster number
        unsigned char name11_12[4];     // last 2 characters in name
};

如果插槽的布局看起来有点奇怪,那只是因为 Microsoft 努力保持与旧软件的兼容性。 必须伪装这些插槽以防止旧软件崩溃。 为此,采取了许多措施

  1. 插槽目录条目的属性字节始终设置为 0x0f。 这对应于具有“隐藏”、“系统”、“只读”和“卷标”属性的旧目录条目。 大多数旧软件会忽略任何设置了“卷标”位的目录条目。 真正的卷标条目没有设置其他三个位。

  2. 起始簇始终设置为 0,这是 DOS 文件的不可能的值。

由于扩展 FAT 系统是向后兼容的,因此旧软件可以修改目录条目。 必须采取措施以确保插槽的有效性。 扩展 FAT 系统可以通过以下方式验证插槽是否确实属于 8.3 目录条目

  1. 定位。 文件的插槽始终紧随其对应的 8.3 目录条目。 此外,每个插槽都有一个 ID,用于标记其在扩展文件名中的顺序。 这是 8.3 目录条目的非常简短的视图及其对应的长名称插槽,用于文件 “My Big File.Extension which is long”

    <proceeding files...>
    <slot #3, id = 0x43, characters = "h is long">
    <slot #2, id = 0x02, characters = "xtension whic">
    <slot #1, id = 0x01, characters = "My Big File.E">
    <directory entry, name = "MYBIGFIL.EXT">
    

    注意

    请注意,插槽从最后一个到第一个存储。 插槽编号从 1 到 N。第 N 个插槽 或与 0x40 一起标记为最后一个。

  2. 校验和。 每个插槽都有一个 alias_checksum 值。 校验和使用以下算法从 8.3 名称计算

    for (sum = i = 0; i < 11; i++) {
            sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + name[i]
    }
    
  3. 如果最后一个插槽中有可用空间,则 Unicode NULL (0x0000) 存储在最后一个字符之后。 之后,最后一个插槽中所有未使用的字符都设置为 Unicode 0xFFFF。

最后,请注意,扩展名以 Unicode 存储。 每个 Unicode 字符占用两个或四个字节,以 UTF-16LE 编码。