요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
====
VFAT
====
USING VFAT
==========
To use the vfat filesystem, use the filesystem type 'vfat'. i.e.::
mount -t vfat /dev/fd0 /mnt
No special partition formatter is required,
'mkdosfs' will work fine if you want to format from within Linux.
VFAT MOUNT OPTIONS
==================
**uid=###**
Set the owner of all files on this filesystem.
The default is the uid of current process.
**gid=###**
Set the group of all files on this filesystem.
The default is the gid of current process.
**umask=###**
The permission mask (for files and directories, see *umask(1)*).
The default is the umask of current process.
**dmask=###**
The permission mask for the directory.
The default is the umask of current process.
**fmask=###**
The permission mask for files.
The default is the umask of current process.
**allow_utime=###**
This option controls the permission check of mtime/atime.
**-20**: If current process is in group of file's group ID,
you can change timestamp.
**-2**: Other users can change timestamp.
The default is set from dmask option. If the directory is
writable, utime(2) is also allowed. i.e. ~dmask & 022.
Normally utime(2) checks current process is owner of
the file, or it has CAP_FOWNER capability. But FAT
filesystem doesn't have uid/gid on disk, so normal
check is too inflexible. With this option you can
relax it.
**codepage=###**
Sets the codepage number for converting to shortname
characters on FAT filesystem.
By default, FAT_DEFAULT_CODEPAGE setting is used.
**iocharset=<name>**
Character set to use for converting between the
encoding is used for user visible filename and 16 bit
Unicode characters. Long filenames are stored on disk
in Unicode format, but Unix for the most part doesn't
know how to deal with Unicode.
By default, FAT_DEFAULT_IOCHARSET setting is used.
There is also an option of doing UTF-8 translations
with the utf8 option.
.. note:: ``iocharset=utf8`` is not recommended. If unsure, you should consider
the utf8 option instead.
**utf8=<bool>**
UTF-8 is the filesystem safe version of Unicode that
is used by the console. It can be enabled or disabled
for the filesystem with this option.
If 'uni_xlate' gets set, UTF-8 gets disabled.
By default, FAT_DEFAULT_UTF8 setting is used.
**uni_xlate=<bool>**
Translate unhandled Unicode characters to special
escaped sequences. This would let you backup and
restore filenames that are created with any Unicode
characters. Until Linux supports Unicode for real,
this gives you an alternative. Without this option,
a '?' is used when no translation is possible. The
escape character is ':' because it is otherwise
illegal on the vfat filesystem. The escape sequence
that gets used is ':' and the four digits of hexadecimal
unicode.
**nonumtail=<bool>**
When creating 8.3 aliases, normally the alias will
end in '~1' or tilde followed by some number. If this
option is set, then if the filename is
"longfilename.txt" and "longfile.txt" does not
currently exist in the directory, longfile.txt will
be the short alias instead of longfi~1.txt.
**usefree**
Use the "free clusters" value stored on FSINFO. It will
be used to determine number of free clusters without
scanning disk. But it's not used by default, because
recent Windows don't update it correctly in some
case. If you are sure the "free clusters" on FSINFO is
correct, by this option you can avoid scanning disk.
**quiet**
Stops printing certain warning messages.
**check=s|r|n**
Case sensitivity checking setting.
**s**: strict, case sensitive
**r**: relaxed, case insensitive
**n**: normal, default setting, currently case insensitive
**nocase**
This was deprecated for vfat. Use ``shortname=win95`` instead.
**shortname=lower|win95|winnt|mixed**
Shortname display/create setting.
**lower**: convert to lowercase for display,
emulate the Windows 95 rule for create.
**win95**: emulate the Windows 95 rule for display/create.
**winnt**: emulate the Windows NT rule for display/create.
**mixed**: emulate the Windows NT rule for display,
emulate the Windows 95 rule for create.
Default setting is `mixed`.
**tz=UTC**
Interpret timestamps as UTC rather than local time.
This option disables the conversion of timestamps
between local time (as used by Windows on FAT) and UTC
(which Linux uses internally). This is particularly
useful when mounting devices (like digital cameras)
that are set to UTC in order to avoid the pitfalls of
local time.
**time_offset=minutes**
Set offset for conversion of timestamps from local time
used by FAT to UTC. I.e. <minutes> minutes will be subtracted
from each timestamp to convert it to UTC used internally by
Linux. This is useful when time zone set in ``sys_tz`` is
not the time zone used by the filesystem. Note that this
option still does not provide correct time stamps in all
cases in presence of DST - time stamps in a different DST
setting will be off by one hour.
**showexec**
If set, the execute permission bits of the file will be
allowed only if the extension part of the name is .EXE,
.COM, or .BAT. Not set by default.
**debug**
Can be set, but unused by the current implementation.
**sys_immutable**
If set, ATTR_SYS attribute on FAT is handled as
IMMUTABLE flag on Linux. Not set by default.
**flush**
If set, the filesystem will try to flush to disk more
early than normal. Not set by default.
**rodir**
FAT has the ATTR_RO (read-only) attribute. On Windows,
the ATTR_RO of the directory will just be ignored,
and is used only by applications as a flag (e.g. it's set
for the customized folder).
If you want to use ATTR_RO as read-only flag even for
the directory, set this option.
**errors=panic|continue|remount-ro**
specify FAT behavior on critical errors: panic, continue
without doing anything or remount the partition in
read-only mode (default behavior).
**discard**
If set, issues discard/TRIM commands to the block
device when blocks are freed. This is useful for SSD devices
and sparse/thinly-provisioned LUNs.
**nfs=stale_rw|nostale_ro**
Enable this only if you want to export the FAT filesystem
over NFS.
**stale_rw**: This option maintains an index (cache) of directory
*inodes* by *i_logstart* which is used by the nfs-related code to
improve look-ups. Full file operations (read/write) over NFS is
supported but with cache eviction at NFS server, this could
result in ESTALE issues.
**nostale_ro**: This option bases the *inode* number and filehandle
on the on-disk location of a file in the MS-DOS directory entry.
This ensures that ESTALE will not be returned after a file is
evicted from the inode cache. However, it means that operations
such as rename, create and unlink could cause filehandles that
previously pointed at one file to point at a different file,
potentially causing data corruption. For this reason, this
option also mounts the filesystem readonly.
To maintain backward compatibility, ``'-o nfs'`` is also accepted,
defaulting to "stale_rw".
**dos1xfloppy <bool>: 0,1,yes,no,true,false**
If set, use a fallback default BIOS Parameter Block
configuration, determined by backing device size. These static
parameters match defaults assumed by DOS 1.x for 160 kiB,
180 kiB, 320 kiB, and 360 kiB floppies and floppy images.
LIMITATION
==========
The fallocated region of file is discarded at umount/evict time
when using fallocate with FALLOC_FL_KEEP_SIZE.
So, User should assume that fallocated region can be discarded at
last close if there is memory pressure resulting in eviction of
the inode from the memory. As a result, for any dependency on
the fallocated region, user should make sure to recheck fallocate
after reopening the file.
TODO
====
Need to get rid of the raw scanning stuff. Instead, always use
a get next directory entry approach. The only thing left that uses
raw scanning is the directory renaming code.
POSSIBLE PROBLEMS
=================
- vfat_valid_longname does not properly checked reserved names.
- When a volume name is the same as a directory name in the root
directory of the filesystem, the directory name sometimes shows
up as an empty file.
- autoconv option does not work correctly.
TEST SUITE
==========
If you plan to make any modifications to the vfat filesystem, please
get the test suite that comes with the vfat distribution at
`<http://web.archive.org/web/*/http://bmrc.berkeley.edu/people/chaffee/vfat.html>`_
This tests quite a few parts of the vfat filesystem and additional
tests for new features or untested features would be appreciated.
NOTES ON THE STRUCTURE OF THE VFAT FILESYSTEM
=============================================
This documentation was provided by Galen C. Hunt [email protected] and
lightly annotated by Gordon Chaffee.
This document presents a very rough, technical overview of my
knowledge of the extended FAT file system used in Windows NT 3.5 and
Windows 95. I don't guarantee that any of the following is correct,
but it appears to be so.
The extended FAT file system is almost identical to the FAT
file system used in DOS versions up to and including *6.223410239847*
:-). The significant change has been the addition of long file names.
These names support up to 255 characters including spaces and lower
case characters as opposed to the traditional 8.3 short names.
Here is the description of the traditional FAT entry in the current
Windows 95 filesystem::
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
};
The lcase field specifies if the base and/or the extension of an 8.3
name should be capitalized. This field does not seem to be used by
Windows 95 but it is used by Windows NT. The case of filenames is not
completely compatible from Windows NT to Windows 95. It is not completely
compatible in the reverse direction, however. Filenames that fit in
the 8.3 namespace and are written on Windows NT to be lowercase will
show up as uppercase on Windows 95.
.. note:: Note that the ``start`` and ``size`` values are actually little
endian integer values. The descriptions of the fields in this
structure are public knowledge and can be found elsewhere.
With the extended FAT system, Microsoft has inserted extra
directory entries for any files with extended names. (Any name which
legally fits within the old 8.3 encoding scheme does not have extra
entries.) I call these extra entries slots. Basically, a slot is a
specially formatted directory entry which holds up to 13 characters of
a file's extended name. Think of slots as additional labeling for the
directory entry of the file to which they correspond. Microsoft
prefers to refer to the 8.3 entry for a file as its alias and the
extended slot directory entries as the file name.
The C structure for a slot directory entry follows::
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
};
If the layout of the slots looks a little odd, it's only
because of Microsoft's efforts to maintain compatibility with old
software. The slots must be disguised to prevent old software from
panicking. To this end, a number of measures are taken:
1) The attribute byte for a slot directory entry is always set
to 0x0f. This corresponds to an old directory entry with
attributes of "hidden", "system", "read-only", and "volume
label". Most old software will ignore any directory
entries with the "volume label" bit set. Real volume label
entries don't have the other three bits set.
2) The starting cluster is always set to 0, an impossible
value for a DOS file.
Because the extended FAT system is backward compatible, it is
possible for old software to modify directory entries. Measures must
be taken to ensure the validity of slots. An extended FAT system can
verify that a slot does in fact belong to an 8.3 directory entry by
the following:
1) Positioning. Slots for a file always immediately proceed
their corresponding 8.3 directory entry. In addition, each
slot has an id which marks its order in the extended file
name. Here is a very abbreviated view of an 8.3 directory
entry and its corresponding long name slots for the file
"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">
.. note:: Note that the slots are stored from last to first. Slots
are numbered from 1 to N. The Nth slot is ``or'ed`` with
0x40 to mark it as the last one.
2) Checksum. Each slot has an alias_checksum value. The
checksum is calculated from the 8.3 name using the
following algorithm::
for (sum = i = 0; i < 11; i++) {
sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + name[i]
}
3) If there is free space in the final slot, a Unicode ``NULL (0x0000)``
is stored after the final character. After that, all unused
characters in the final slot are set to Unicode 0xFFFF.
Finally, note that the extended name is stored in Unicode. Each Unicode
character takes either two or four bytes, UTF-16LE encoded.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
VFAT 사용과 포맷
1-15VFAT 파일 시스템을 사용하려면 파일 시스템 형식으로 `vfat`을 지정한다. 예를 들어 `mount -t vfat /dev/fd0 /mnt`는 `/dev/fd0`을 `/mnt`에 VFAT으로 마운트한다.
특수한 partition formatter는 필요하지 않다. Linux 안에서 매체를 포맷하려면 `mkdosfs`를 사용하면 된다. 즉, 포맷 단계와 마운트 단계 모두 기존 FAT 도구와 `vfat` 형식 지정으로 처리할 수 있다.
빈 매체 준비부터 파일 시스템 사용까지의 최소 경로다.
====
VFAT
====
USING VFAT
==========
To use the vfat filesystem, use the filesystem type 'vfat'. i.e.::
mount -t vfat /dev/fd0 /mnt
No special partition formatter is required,
'mkdosfs' will work fine if you want to format from within Linux.
소유권·권한·시간 변경 옵션
16-54`uid=###`은 이 파일 시스템의 모든 파일 소유자를 설정하며 기본값은 현재 process의 uid다. `gid=###`은 모든 파일의 group을 설정하며 기본값은 현재 process의 gid다. FAT 디스크 자체에는 Unix uid와 gid가 없으므로 이 값들은 마운트 전체에 보이는 소유권을 정한다.
`umask=###`은 파일과 directory 모두의 permission mask이며 기본값은 현재 process의 umask다. `dmask=###`은 directory 전용 mask, `fmask=###`은 file 전용 mask이고 둘 다 기본값은 현재 process의 umask다.
`allow_utime=###`은 mtime과 atime 변경 권한 검사를 제어한다. 값 `-20`은 현재 process가 파일 group ID의 group에 속하면 timestamp 변경을 허용하고, `-2`는 다른 사용자도 timestamp를 변경하도록 허용한다.
기본 `allow_utime` 값은 `dmask`에서 계산된다. directory에 쓰기 권한이 있으면 `utime(2)`도 허용되며 식은 `~dmask & 022`다. 보통 `utime(2)`은 현재 process가 파일 소유자이거나 `CAP_FOWNER` capability를 가졌는지 검사하지만, FAT에는 디스크 상의 uid/gid가 없어 이 검사가 지나치게 경직될 수 있다. `allow_utime`은 그 검사를 완화한다.
디스크에 Unix 소유권이 없는 FAT를 마운트 시점 속성으로 보완한다.
VFAT MOUNT OPTIONS
==================
**uid=###**
Set the owner of all files on this filesystem.
The default is the uid of current process.
**gid=###**
Set the group of all files on this filesystem.
The default is the gid of current process.
**umask=###**
The permission mask (for files and directories, see *umask(1)*).
The default is the umask of current process.
**dmask=###**
The permission mask for the directory.
The default is the umask of current process.
**fmask=###**
The permission mask for files.
The default is the umask of current process.
**allow_utime=###**
This option controls the permission check of mtime/atime.
**-20**: If current process is in group of file's group ID,
you can change timestamp.
**-2**: Other users can change timestamp.
The default is set from dmask option. If the directory is
writable, utime(2) is also allowed. i.e. ~dmask & 022.
Normally utime(2) checks current process is owner of
the file, or it has CAP_FOWNER capability. But FAT
filesystem doesn't have uid/gid on disk, so normal
check is too inflexible. With this option you can
relax it.
문자 인코딩·Unicode·8.3 alias
55-109`codepage=###`은 FAT shortname 문자로 변환할 codepage 번호를 정하며 기본값은 `FAT_DEFAULT_CODEPAGE`다. `iocharset=<name>`은 사용자에게 보이는 filename 인코딩과 디스크의 16-bit Unicode 문자 사이를 변환할 문자 집합을 정하며 기본값은 `FAT_DEFAULT_IOCHARSET`다.
long filename은 디스크에 Unicode 형식으로 저장된다. UTF-8 변환은 `utf8` 옵션으로 선택할 수 있으며, `iocharset=utf8`은 권장되지 않는다. 확실하지 않다면 `iocharset=utf8` 대신 `utf8` 옵션을 고려해야 한다.
`utf8=<bool>`은 console에서도 사용하는, 파일 시스템에 안전한 Unicode 표현인 UTF-8을 켜거나 끈다. 기본값은 `FAT_DEFAULT_UTF8`이고, `uni_xlate`가 설정되면 UTF-8은 비활성화된다.
`uni_xlate=<bool>`은 처리할 수 없는 Unicode 문자를 특수 escape sequence로 변환한다. 이를 사용하면 임의의 Unicode 문자가 포함된 filename을 backup하고 restore할 수 있다. 옵션이 없고 변환할 수 없으면 `?`를 사용한다. escape 문자는 VFAT filename에서는 원래 허용되지 않는 `:`이며, escape sequence는 `:` 뒤에 4자리 hexadecimal Unicode 값을 붙인 형태다.
`nonumtail=<bool>`은 8.3 alias 생성 규칙을 바꾼다. 보통 alias 끝에는 `~1` 같은 숫자 tail이 붙는다. 이 옵션을 켜고 `longfilename.txt`를 만들 때 directory에 `longfile.txt`가 없다면 `longfi~1.txt` 대신 `longfile.txt`를 short alias로 사용한다.
`usefree`는 FSINFO에 저장된 `free clusters` 값을 사용해 디스크 스캔 없이 free cluster 수를 판단한다. 최근 Windows가 일부 상황에서 이 값을 정확히 갱신하지 않으므로 기본값은 아니다. FSINFO 값이 정확하다고 확신할 때만 스캔을 피하기 위해 사용해야 한다.
shortname codepage, long filename Unicode와 8.3 alias 생성을 구분한다.
디스크의 Unicode 이름이 사용자 공간 이름으로 보이는 경로다.
**codepage=###**
Sets the codepage number for converting to shortname
characters on FAT filesystem.
By default, FAT_DEFAULT_CODEPAGE setting is used.
**iocharset=<name>**
Character set to use for converting between the
encoding is used for user visible filename and 16 bit
Unicode characters. Long filenames are stored on disk
in Unicode format, but Unix for the most part doesn't
know how to deal with Unicode.
By default, FAT_DEFAULT_IOCHARSET setting is used.
There is also an option of doing UTF-8 translations
with the utf8 option.
.. note:: ``iocharset=utf8`` is not recommended. If unsure, you should consider
the utf8 option instead.
**utf8=<bool>**
UTF-8 is the filesystem safe version of Unicode that
is used by the console. It can be enabled or disabled
for the filesystem with this option.
If 'uni_xlate' gets set, UTF-8 gets disabled.
By default, FAT_DEFAULT_UTF8 setting is used.
**uni_xlate=<bool>**
Translate unhandled Unicode characters to special
escaped sequences. This would let you backup and
restore filenames that are created with any Unicode
characters. Until Linux supports Unicode for real,
this gives you an alternative. Without this option,
a '?' is used when no translation is possible. The
escape character is ':' because it is otherwise
illegal on the vfat filesystem. The escape sequence
that gets used is ':' and the four digits of hexadecimal
unicode.
**nonumtail=<bool>**
When creating 8.3 aliases, normally the alias will
end in '~1' or tilde followed by some number. If this
option is set, then if the filename is
"longfilename.txt" and "longfile.txt" does not
currently exist in the directory, longfile.txt will
be the short alias instead of longfi~1.txt.
**usefree**
Use the "free clusters" value stored on FSINFO. It will
be used to determine number of free clusters without
scanning disk. But it's not used by default, because
recent Windows don't update it correctly in some
case. If you are sure the "free clusters" on FSINFO is
correct, by this option you can avoid scanning disk.
대소문자·shortname·시간·실행 권한
110-165`quiet`은 일부 warning message 출력을 중단한다. `check=s|r|n`은 대소문자 구분 검사를 정한다. `s`는 엄격한 case-sensitive, `r`은 완화된 case-insensitive, `n`은 기본 normal 모드이며 현재는 case-insensitive다.
VFAT에서 `nocase`는 폐기되었으므로 대신 `shortname=win95`를 사용해야 한다. `shortname=lower|win95|winnt|mixed`는 shortname 표시와 생성 규칙을 고른다. `lower`는 표시할 때 소문자로 바꾸고 생성은 Windows 95 규칙을 따른다. `win95`는 표시와 생성 모두 Windows 95 규칙을, `winnt`는 둘 다 Windows NT 규칙을 따른다. `mixed`는 표시에는 Windows NT, 생성에는 Windows 95 규칙을 사용하며 기본값이다.
`tz=UTC`는 timestamp를 local time이 아니라 UTC로 해석한다. Windows가 FAT에서 사용하는 local time과 Linux 내부의 UTC 사이 변환을 비활성화하므로, digital camera처럼 UTC로 설정된 장치를 마운트할 때 local time의 함정을 피하는 데 유용하다.
`time_offset=minutes`는 FAT의 local timestamp를 UTC로 변환할 offset을 정한다. 각 timestamp에서 `<minutes>`분을 빼 Linux 내부 UTC로 바꾼다. `sys_tz`의 time zone과 파일 시스템이 사용한 time zone이 다를 때 유용하지만, DST가 있으면 모든 상황에서 정확하지 않다. 서로 다른 DST 설정의 timestamp는 한 시간 어긋날 수 있다.
`showexec`은 filename 확장자가 `.EXE`, `.COM`, `.BAT`인 경우에만 file execute permission bit를 허용하며 기본값은 꺼짐이다. `debug`은 설정할 수 있으나 현재 구현에서는 사용하지 않는다.
대소문자 표시와 생성 규칙, timestamp 해석, 실행 bit의 의미를 정리한다.
**quiet**
Stops printing certain warning messages.
**check=s|r|n**
Case sensitivity checking setting.
**s**: strict, case sensitive
**r**: relaxed, case insensitive
**n**: normal, default setting, currently case insensitive
**nocase**
This was deprecated for vfat. Use ``shortname=win95`` instead.
**shortname=lower|win95|winnt|mixed**
Shortname display/create setting.
**lower**: convert to lowercase for display,
emulate the Windows 95 rule for create.
**win95**: emulate the Windows 95 rule for display/create.
**winnt**: emulate the Windows NT rule for display/create.
**mixed**: emulate the Windows NT rule for display,
emulate the Windows 95 rule for create.
Default setting is `mixed`.
**tz=UTC**
Interpret timestamps as UTC rather than local time.
This option disables the conversion of timestamps
between local time (as used by Windows on FAT) and UTC
(which Linux uses internally). This is particularly
useful when mounting devices (like digital cameras)
that are set to UTC in order to avoid the pitfalls of
local time.
**time_offset=minutes**
Set offset for conversion of timestamps from local time
used by FAT to UTC. I.e. <minutes> minutes will be subtracted
from each timestamp to convert it to UTC used internally by
Linux. This is useful when time zone set in ``sys_tz`` is
not the time zone used by the filesystem. Note that this
option still does not provide correct time stamps in all
cases in presence of DST - time stamps in a different DST
setting will be off by one hour.
**showexec**
If set, the execute permission bits of the file will be
allowed only if the extension part of the name is .EXE,
.COM, or .BAT. Not set by default.
**debug**
Can be set, but unused by the current implementation.
속성·오류·discard·NFS·DOS 1.x
166-220`sys_immutable`은 FAT의 `ATTR_SYS` 속성을 Linux의 `IMMUTABLE` flag로 처리하며 기본값은 꺼짐이다. `flush`는 평소보다 일찍 디스크로 flush하려 시도하며 기본값은 꺼짐이다.
FAT에는 `ATTR_RO` read-only 속성이 있지만 Windows는 directory의 `ATTR_RO`를 무시하고 customized folder 같은 application flag로만 사용한다. directory에도 `ATTR_RO`를 read-only flag로 적용하려면 `rodir`을 지정한다.
`errors=panic|continue|remount-ro`는 critical error가 발생했을 때의 FAT 동작을 정한다. `panic`은 kernel panic, `continue`는 별 조치 없이 계속, `remount-ro`는 partition을 read-only로 다시 마운트하며 기본 동작이다.
`discard`는 block이 해제될 때 block device로 discard/TRIM command를 보낸다. SSD와 sparse 또는 thinly-provisioned LUN에서 유용하다.
`nfs=stale_rw|nostale_ro`는 FAT를 NFS로 export할 때만 켜야 한다. `stale_rw`는 NFS lookup 개선을 위해 directory inode를 `i_logstart` 기준으로 색인한 cache를 유지하고 NFS의 read/write 전체 연산을 지원한다. 다만 NFS server에서 cache가 축출되면 `ESTALE` 문제가 생길 수 있다.
`nostale_ro`는 MS-DOS directory entry 안의 파일 on-disk 위치를 바탕으로 inode number와 filehandle을 만든다. inode cache에서 파일이 축출되어도 `ESTALE`을 반환하지 않지만, rename·create·unlink 뒤에는 기존 filehandle이 다른 파일을 가리켜 data corruption을 일으킬 수 있다. 이 위험 때문에 파일 시스템을 read-only로 마운트한다. 호환성을 위해 `-o nfs`도 허용하며 기본적으로 `stale_rw`가 된다.
`dos1xfloppy <bool>`은 하위 장치 크기로 결정되는 기본 BIOS Parameter Block 구성을 fallback으로 사용한다. 정적 parameter는 DOS 1.x가 160KiB, 180KiB, 320KiB, 360KiB floppy와 image에 가정한 기본값과 일치한다.
Linux flag 매핑, 쓰기 정책과 하위 장치 알림을 제어한다.
read/write 가능성과 filehandle 안정성 사이의 절충이다.
**sys_immutable**
If set, ATTR_SYS attribute on FAT is handled as
IMMUTABLE flag on Linux. Not set by default.
**flush**
If set, the filesystem will try to flush to disk more
early than normal. Not set by default.
**rodir**
FAT has the ATTR_RO (read-only) attribute. On Windows,
the ATTR_RO of the directory will just be ignored,
and is used only by applications as a flag (e.g. it's set
for the customized folder).
If you want to use ATTR_RO as read-only flag even for
the directory, set this option.
**errors=panic|continue|remount-ro**
specify FAT behavior on critical errors: panic, continue
without doing anything or remount the partition in
read-only mode (default behavior).
**discard**
If set, issues discard/TRIM commands to the block
device when blocks are freed. This is useful for SSD devices
and sparse/thinly-provisioned LUNs.
**nfs=stale_rw|nostale_ro**
Enable this only if you want to export the FAT filesystem
over NFS.
**stale_rw**: This option maintains an index (cache) of directory
*inodes* by *i_logstart* which is used by the nfs-related code to
improve look-ups. Full file operations (read/write) over NFS is
supported but with cache eviction at NFS server, this could
result in ESTALE issues.
**nostale_ro**: This option bases the *inode* number and filehandle
on the on-disk location of a file in the MS-DOS directory entry.
This ensures that ESTALE will not be returned after a file is
evicted from the inode cache. However, it means that operations
such as rename, create and unlink could cause filehandles that
previously pointed at one file to point at a different file,
potentially causing data corruption. For this reason, this
option also mounts the filesystem readonly.
To maintain backward compatibility, ``'-o nfs'`` is also accepted,
defaulting to "stale_rw".
**dos1xfloppy <bool>: 0,1,yes,no,true,false**
If set, use a fallback default BIOS Parameter Block
configuration, determined by backing device size. These static
parameters match defaults assumed by DOS 1.x for 160 kiB,
180 kiB, 320 kiB, and 360 kiB floppies and floppy images.
제한·TODO·알려진 문제·시험 모음
221-260`FALLOC_FL_KEEP_SIZE`로 `fallocate`한 file 영역은 unmount 또는 inode eviction 시 버려진다. memory pressure로 inode가 memory에서 축출되면 마지막 close 시점에도 fallocated region이 사라질 수 있다고 가정해야 한다. 이 영역에 의존하는 사용자는 파일을 다시 연 뒤 `fallocate` 상태를 반드시 재확인해야 한다.
TODO는 raw scanning을 없애고 항상 다음 directory entry를 얻는 접근법을 사용하는 것이다. 현재 raw scanning을 여전히 사용하는 부분은 directory rename code뿐이다.
알려진 문제는 세 가지다. `vfat_valid_longname`이 reserved name을 올바르게 검사하지 않고, volume name이 root directory의 directory name과 같으면 그 directory가 때때로 빈 file로 보이며, `autoconv` 옵션이 올바르게 동작하지 않는다.
VFAT 파일 시스템을 수정하려면 VFAT 배포판의 test suite를 받아 실행해야 한다. 보관된 주소는 `http://web.archive.org/web/*/http://bmrc.berkeley.edu/people/chaffee/vfat.html`이다. 이 시험은 VFAT의 여러 부분을 검사하며 새 기능이나 아직 시험되지 않은 기능을 위한 추가 test도 환영한다.
운영 제한과 개발 시 확인할 알려진 항목을 구분한다.
LIMITATION
==========
The fallocated region of file is discarded at umount/evict time
when using fallocate with FALLOC_FL_KEEP_SIZE.
So, User should assume that fallocated region can be discarded at
last close if there is memory pressure resulting in eviction of
the inode from the memory. As a result, for any dependency on
the fallocated region, user should make sure to recheck fallocate
after reopening the file.
TODO
====
Need to get rid of the raw scanning stuff. Instead, always use
a get next directory entry approach. The only thing left that uses
raw scanning is the directory renaming code.
POSSIBLE PROBLEMS
=================
- vfat_valid_longname does not properly checked reserved names.
- When a volume name is the same as a directory name in the root
directory of the filesystem, the directory name sometimes shows
up as an empty file.
- autoconv option does not work correctly.
TEST SUITE
==========
If you plan to make any modifications to the vfat filesystem, please
get the test suite that comes with the vfat distribution at
`<http://web.archive.org/web/*/http://bmrc.berkeley.edu/people/chaffee/vfat.html>`_
This tests quite a few parts of the vfat filesystem and additional
tests for new features or untested features would be appreciated.
전통적인 FAT directory entry
261-309이 구조 설명은 Galen C. Hunt가 제공하고 Gordon Chaffee가 간단히 주석을 보탰다. Windows NT 3.5와 Windows 95에서 사용한 extended FAT에 관한 매우 거친 기술 개요이며, 원 작성자는 정확성을 보증하지 않는다고 명시한다.
extended FAT는 DOS `6.223410239847`까지의 FAT와 거의 같고 중요한 변화는 long filename의 추가다. 전통적인 8.3 shortname과 달리 long filename은 space와 lowercase를 포함해 최대 255자를 지원한다.
전통적인 FAT의 `struct directory`는 8바이트 base name, 3바이트 extension, attribute, base와 extension의 case, 생성 시각과 날짜, 마지막 접근 날짜, timestamp, 시작 cluster, file size 등을 저장한다.
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` field는 8.3 name의 base와 extension을 대문자로 표시할지 지정한다. Windows 95는 이 field를 사용하지 않는 것으로 보이지만 Windows NT는 사용한다. 따라서 case 동작은 양방향으로 완전히 호환되지 않는다. Windows NT에서 lowercase로 기록한 8.3 filename은 Windows 95에서 uppercase로 보인다.
`start`와 `size` 값은 실제로 little-endian integer다. 이 structure field 설명은 공개적으로 알려진 형식이며 다른 자료에서도 확인할 수 있다.
`struct directory`의 byte 배열을 논리적 역할별로 묶는다.
NOTES ON THE STRUCTURE OF THE VFAT FILESYSTEM
=============================================
This documentation was provided by Galen C. Hunt [email protected] and
lightly annotated by Gordon Chaffee.
This document presents a very rough, technical overview of my
knowledge of the extended FAT file system used in Windows NT 3.5 and
Windows 95. I don't guarantee that any of the following is correct,
but it appears to be so.
The extended FAT file system is almost identical to the FAT
file system used in DOS versions up to and including *6.223410239847*
:-). The significant change has been the addition of long file names.
These names support up to 255 characters including spaces and lower
case characters as opposed to the traditional 8.3 short names.
Here is the description of the traditional FAT entry in the current
Windows 95 filesystem::
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
};
The lcase field specifies if the base and/or the extension of an 8.3
name should be capitalized. This field does not seem to be used by
Windows 95 but it is used by Windows NT. The case of filenames is not
completely compatible from Windows NT to Windows 95. It is not completely
compatible in the reverse direction, however. Filenames that fit in
the 8.3 namespace and are written on Windows NT to be lowercase will
show up as uppercase on Windows 95.
.. note:: Note that the ``start`` and ``size`` values are actually little
endian integer values. The descriptions of the fields in this
structure are public knowledge and can be found elsewhere.
Long filename slot 구조
310-337extended FAT는 old 8.3 encoding에 합법적으로 들어가지 않는 extended name을 가진 파일 앞에 추가 directory entry를 넣는다. 원문은 이 추가 entry를 slot이라고 부른다. old 8.3 형식에 맞는 이름에는 추가 slot이 없다.
slot은 파일의 extended name을 최대 13자까지 담는 특수 형식의 directory entry다. 대응하는 파일의 8.3 directory entry에 추가 label을 붙인 것으로 볼 수 있다. Microsoft 용어에서는 파일의 8.3 entry가 alias이고 extended slot directory entry들이 file name이다.
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
};
`struct slot`은 순서를 나타내는 `id`, 세 구간으로 나뉜 이름 문자 배열, 고정 attribute, 항상 0인 reserved byte, 8.3 alias의 checksum, 시작 cluster field를 가진다. 이름 배열은 5자·6자·2자를 담아 slot 하나당 총 13자를 구성한다.
호환성을 유지한 directory entry 안에 13자 이름과 검증 정보를 배치한다.
하나의 파일 이름을 longname slot과 8.3 entry가 함께 표현한다.
With the extended FAT system, Microsoft has inserted extra
directory entries for any files with extended names. (Any name which
legally fits within the old 8.3 encoding scheme does not have extra
entries.) I call these extra entries slots. Basically, a slot is a
specially formatted directory entry which holds up to 13 characters of
a file's extended name. Think of slots as additional labeling for the
directory entry of the file to which they correspond. Microsoft
prefers to refer to the 8.3 entry for a file as its alias and the
extended slot directory entries as the file name.
The C structure for a slot directory entry follows::
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
};
If the layout of the slots looks a little odd, it's only
because of Microsoft's efforts to maintain compatibility with old
software. The slots must be disguised to prevent old software from
panicking. To this end, a number of measures are taken:
Slot 위장·순서·checksum 검증
338-384slot 배치가 특이한 이유는 old software와의 호환성을 유지하려는 Microsoft의 설계 때문이다. old software가 slot을 보고 오동작하지 않도록 slot directory entry의 attribute byte는 항상 `0x0f`다. 이는 old entry에서 hidden, system, read-only, volume label 속성이 모두 켜진 값이다. old software는 보통 volume label bit가 켜진 entry를 무시하며, 실제 volume label entry에는 나머지 세 bit가 함께 켜지지 않는다.
slot의 starting cluster는 항상 0이다. 0은 DOS file에는 불가능한 값이므로 slot을 정상 파일 entry와 구분하는 또 하나의 표식이다.
extended FAT는 backward compatible하므로 old software가 directory entry를 수정할 수 있다. slot의 유효성은 위치와 checksum으로 검증한다. 한 파일의 slot은 대응하는 8.3 directory entry 바로 앞에 연속해서 놓이며 각 slot의 `id`가 extended filename 안의 순서를 표시한다.
`My Big File.Extension which is long`의 경우 디스크 순서는 마지막 문자열을 담은 slot #3, slot #2, 첫 문자열을 담은 slot #1, `MYBIGFIL.EXT` directory entry다. 즉 slot은 마지막 조각부터 첫 조각 순서로 저장된다. slot 번호는 1부터 N이며 N번째 slot의 `id`에는 마지막 slot임을 표시하도록 `0x40`을 OR한다.
old software에는 무시되는 entry로 보이면서 VFAT에는 식별 가능해야 한다.
`My Big File.Extension which is long`이 마지막 조각부터 저장되는 예다.
각 slot의 `alias_checksum`은 8.3 name의 11바이트에서 다음 algorithm으로 계산한다. 매 반복에서 sum을 1bit 회전한 뒤 현재 name byte를 더한다.
for (sum = i = 0; i < 11; i++) {
sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + name[i]
}
마지막 slot에 빈 공간이 있으면 최종 문자 뒤에 Unicode `NULL (0x0000)`을 저장한다. 그 뒤 마지막 slot의 사용하지 않는 모든 문자 위치는 Unicode `0xFFFF`로 채운다.
1) The attribute byte for a slot directory entry is always set
to 0x0f. This corresponds to an old directory entry with
attributes of "hidden", "system", "read-only", and "volume
label". Most old software will ignore any directory
entries with the "volume label" bit set. Real volume label
entries don't have the other three bits set.
2) The starting cluster is always set to 0, an impossible
value for a DOS file.
Because the extended FAT system is backward compatible, it is
possible for old software to modify directory entries. Measures must
be taken to ensure the validity of slots. An extended FAT system can
verify that a slot does in fact belong to an 8.3 directory entry by
the following:
1) Positioning. Slots for a file always immediately proceed
their corresponding 8.3 directory entry. In addition, each
slot has an id which marks its order in the extended file
name. Here is a very abbreviated view of an 8.3 directory
entry and its corresponding long name slots for the file
"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">
.. note:: Note that the slots are stored from last to first. Slots
are numbered from 1 to N. The Nth slot is ``or'ed`` with
0x40 to mark it as the last one.
2) Checksum. Each slot has an alias_checksum value. The
checksum is calculated from the 8.3 name using the
following algorithm::
for (sum = i = 0; i < 11; i++) {
sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + name[i]
}
3) If there is free space in the final slot, a Unicode ``NULL (0x0000)``
is stored after the final character. After that, all unused
characters in the final slot are set to Unicode 0xFFFF.
Extended name의 UTF-16LE 저장
385-387마지막으로 extended name은 Unicode로 저장된다. 각 Unicode 문자는 UTF-16LE로 인코딩되어 2바이트 또는 4바이트를 차지한다. Basic Multilingual Plane 문자는 보통 2바이트 code unit 하나로, 그 밖의 문자는 surrogate pair 두 개로 표현되어 4바이트가 된다.
따라서 slot의 이름 배열은 byte 수만 보고 문자 수를 계산해서는 안 된다. slot 하나의 논리적 한도는 13자이지만 supplementary character가 포함되면 UTF-16 code unit과 사용자에게 보이는 문자 수의 차이를 고려해야 한다.
extended name 문자가 UTF-16LE byte로 기록되는 경로다.
Finally, note that the extended name is stored in Unicode. Each Unicode
character takes either two or four bytes, UTF-16LE encoded.
요약·해설
vfat.rst:1-387VFAT는 FAT의 8.3 directory entry를 유지하면서 long filename slot을 바로 앞에 추가해 최대 255자의 Unicode 이름을 제공한다. slot은 13자씩 이름을 담고 역순으로 저장되며, 위치·id·8.3 alias checksum으로 소속과 순서를 검증한다.
마운트 옵션은 디스크에 없는 Unix 소유권·권한을 합성하고, shortname codepage와 long filename Unicode 변환, Windows 95/NT 대소문자 규칙, timestamp 해석, 오류 처리, discard와 NFS export 동작을 정한다.
NFS의 `stale_rw`와 `nostale_ro`, `usefree`, `time_offset`, `FALLOC_FL_KEEP_SIZE` 제한은 성능과 안정성의 절충이 있으므로 기본 동작을 바꾸기 전에 매체와 workload를 확인해야 한다.
long filename과 old 8.3 호환 entry가 하나의 파일을 표현한다.