← Documents Documentation/filesystems/hpfs.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

Read/Write HPFS 2.09

Linux HPFS driver의 mount option, filename·EA·codepage 동작, 알려진 bug와 전체 version history를 설명하는 전문 번역입니다.

Source pathDocumentation/filesystems/hpfs.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

hpfs.rst:1-353

Linux HPFS 2.09 driver는 OS/2 HPFS의 read/write, Unix permission EA, Linux-only symlink와 여러 오류 정책을 제공합니다. 실제 운용에서는 `check=normal`, `errors=remount-ro`, 적절한 `eas` 정책을 기본으로 두고 HPFS386 server volume은 read-only로 다루는 편이 안전합니다.

가장 큰 호환성 위험은 mixed codepage, OS/2와 Linux의 filename·path·symlink 차이, 공간 부족 시 EA truncate와 directory delete 실패입니다. 0.90~2.09 history는 이 driver가 race, allocation, large disk, directory tree와 OS/2 compatibility를 단계적으로 보완해 온 과정을 보여 줍니다.

HPFS 안전 운용 점검
`check=normal` 이상과 `errors=remount-ro` 유지UID/GID/MODE/DEV/SYMLINK EA 정책 확인한 volume에서 OS/2 language·codepage 혼용 금지HPFS386 server volume은 read-only 사용긴 path·full directory band·unbalanced tree warning 감시

mount부터 OS/2 interoperability까지 확인할 항목입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ====================
4 Read/Write HPFS 2.09
5 ====================
6
7 1998-2004, Mikulas Patocka
8
9 :email: mikulas@artax.karlin.mff.cuni.cz
10 :homepage: https://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
11
12 Credits
13 =======
14 Chris Smith, 1993, original read-only HPFS, some code and hpfs structures file
15 is taken from it
16
17 Jacques Gelinas, MSDos mmap, Inspired by fs/nfs/mmap.c (Jon Tombs 15 Aug 1993)
18
19 Werner Almesberger, 1992, 1993, MSDos option parser & CR/LF conversion
20
21 Mount options
22
23 uid=xxx,gid=xxx,umask=xxx (default uid=gid=0 umask=default_system_umask)
24 Set owner/group/mode for files that do not have it specified in extended
25 attributes. Mode is inverted umask - for example umask 027 gives owner
26 all permission, group read permission and anybody else no access. Note
27 that for files mode is anded with 0666. If you want files to have 'x'
28 rights, you must use extended attributes.
29 case=lower,asis (default asis)
30 File name lowercasing in readdir.
31 conv=binary,text,auto (default binary)
32 CR/LF -> LF conversion, if auto, decision is made according to extension
33 - there is a list of text extensions (I thing it's better to not convert
34 text file than to damage binary file). If you want to change that list,
35 change it in the source. Original readonly HPFS contained some strange
36 heuristic algorithm that I removed. I thing it's danger to let the
37 computer decide whether file is text or binary. For example, DJGPP
38 binaries contain small text message at the beginning and they could be
39 misidentified and damaged under some circumstances.
40 check=none,normal,strict (default normal)
41 Check level. Selecting none will cause only little speedup and big
42 danger. I tried to write it so that it won't crash if check=normal on
43 corrupted filesystems. check=strict means many superfluous checks -
44 used for debugging (for example it checks if file is allocated in
45 bitmaps when accessing it).
46 errors=continue,remount-ro,panic (default remount-ro)
47 Behaviour when filesystem errors found.
48 chkdsk=no,errors,always (default errors)
49 When to mark filesystem dirty so that OS/2 checks it.
50 eas=no,ro,rw (default rw)
51 What to do with extended attributes. 'no' - ignore them and use always
52 values specified in uid/gid/mode options. 'ro' - read extended
53 attributes but do not create them. 'rw' - create extended attributes
54 when you use chmod/chown/chgrp/mknod/ln -s on the filesystem.
55 timeshift=(-)nnn (default 0)
56 Shifts the time by nnn seconds. For example, if you see under linux
57 one hour more, than under os/2, use timeshift=-3600.
58
59
60 File names
61 ==========
62
63 As in OS/2, filenames are case insensitive. However, shell thinks that names
64 are case sensitive, so for example when you create a file FOO, you can use
65 'cat FOO', 'cat Foo', 'cat foo' or 'cat F*' but not 'cat f*'. Note, that you
66 also won't be able to compile linux kernel (and maybe other things) on HPFS
67 because kernel creates different files with names like bootsect.S and
68 bootsect.s. When searching for file whose name has characters >= 128, codepages
69 are used - see below.
70 OS/2 ignores dots and spaces at the end of file name, so this driver does as
71 well. If you create 'a. ...', the file 'a' will be created, but you can still
72 access it under names 'a.', 'a..', 'a . . . ' etc.
73
74
75 Extended attributes
76 ===================
77
78 On HPFS partitions, OS/2 can associate to each file a special information called
79 extended attributes. Extended attributes are pairs of (key,value) where key is
80 an ascii string identifying that attribute and value is any string of bytes of
81 variable length. OS/2 stores window and icon positions and file types there. So
82 why not use it for unix-specific info like file owner or access rights? This
83 driver can do it. If you chown/chgrp/chmod on a hpfs partition, extended
84 attributes with keys "UID", "GID" or "MODE" and 2-byte values are created. Only
85 that extended attributes those value differs from defaults specified in mount
86 options are created. Once created, the extended attributes are never deleted,
87 they're just changed. It means that when your default uid=0 and you type
88 something like 'chown luser file; chown root file' the file will contain
89 extended attribute UID=0. And when you umount the fs and mount it again with
90 uid=luser_uid, the file will be still owned by root! If you chmod file to 444,
91 extended attribute "MODE" will not be set, this special case is done by setting
92 read-only flag. When you mknod a block or char device, besides "MODE", the
93 special 4-byte extended attribute "DEV" will be created containing the device
94 number. Currently this driver cannot resize extended attributes - it means
95 that if somebody (I don't know who?) has set "UID", "GID", "MODE" or "DEV"
96 attributes with different sizes, they won't be rewritten and changing these
97 values doesn't work.
98
99
100 Symlinks
101 ========
102
103 You can do symlinks on HPFS partition, symlinks are achieved by setting extended
104 attribute named "SYMLINK" with symlink value. Like on ext2, you can chown and
105 chgrp symlinks but I don't know what is it good for. chmoding symlink results
106 in chmoding file where symlink points. These symlinks are just for Linux use and
107 incompatible with OS/2. OS/2 PmShell symlinks are not supported because they are
108 stored in very crazy way. They tried to do it so that link changes when file is
109 moved ... sometimes it works. But the link is partly stored in directory
110 extended attributes and partly in OS2SYS.INI. I don't want (and don't know how)
111 to analyze or change OS2SYS.INI.
112
113
114 Codepages
115 =========
116
117 HPFS can contain several uppercasing tables for several codepages and each
118 file has a pointer to codepage its name is in. However OS/2 was created in
119 America where people don't care much about codepages and so multiple codepages
120 support is quite buggy. I have Czech OS/2 working in codepage 852 on my disk.
121 Once I booted English OS/2 working in cp 850 and I created a file on my 852
122 partition. It marked file name codepage as 850 - good. But when I again booted
123 Czech OS/2, the file was completely inaccessible under any name. It seems that
124 OS/2 uppercases the search pattern with its system code page (852) and file
125 name it's comparing to with its code page (850). These could never match. Is it
126 really what IBM developers wanted? But problems continued. When I created in
127 Czech OS/2 another file in that directory, that file was inaccessible too. OS/2
128 probably uses different uppercasing method when searching where to place a file
129 (note, that files in HPFS directory must be sorted) and when searching for
130 a file. Finally when I opened this directory in PmShell, PmShell crashed (the
131 funny thing was that, when rebooted, PmShell tried to reopen this directory
132 again :-). chkdsk happily ignores these errors and only low-level disk
133 modification saved me. Never mix different language versions of OS/2 on one
134 system although HPFS was designed to allow that.
135 OK, I could implement complex codepage support to this driver but I think it
136 would cause more problems than benefit with such buggy implementation in OS/2.
137 So this driver simply uses first codepage it finds for uppercasing and
138 lowercasing no matter what's file codepage index. Usually all file names are in
139 this codepage - if you don't try to do what I described above :-)
140
141
142 Known bugs
143 ==========
144
145 HPFS386 on OS/2 server is not supported. HPFS386 installed on normal OS/2 client
146 should work. If you have OS/2 server, use only read-only mode. I don't know how
147 to handle some HPFS386 structures like access control list or extended perm
148 list, I don't know how to delete them when file is deleted and how to not
149 overwrite them with extended attributes. Send me some info on these structures
150 and I'll make it. However, this driver should detect presence of HPFS386
151 structures, remount read-only and not destroy them (I hope).
152
153 When there's not enough space for extended attributes, they will be truncated
154 and no error is returned.
155
156 OS/2 can't access files if the path is longer than about 256 chars but this
157 driver allows you to do it. chkdsk ignores such errors.
158
159 Sometimes you won't be able to delete some files on a very full filesystem
160 (returning error ENOSPC). That's because file in non-leaf node in directory tree
161 (one directory, if it's large, has dirents in tree on HPFS) must be replaced
162 with another node when deleted. And that new file might have larger name than
163 the old one so the new name doesn't fit in directory node (dnode). And that
164 would result in directory tree splitting, that takes disk space. Workaround is
165 to delete other files that are leaf (probability that the file is non-leaf is
166 about 1/50) or to truncate file first to make some space.
167 You encounter this problem only if you have many directories so that
168 preallocated directory band is full i.e.::
169
170 number_of_directories / size_of_filesystem_in_mb > 4.
171
172 You can't delete open directories.
173
174 You can't rename over directories (what is it good for?).
175
176 Renaming files so that only case changes doesn't work. This driver supports it
177 but vfs doesn't. Something like 'mv file FILE' won't work.
178
179 All atimes and directory mtimes are not updated. That's because of performance
180 reasons. If you extremely wish to update them, let me know, I'll write it (but
181 it will be slow).
182
183 When the system is out of memory and swap, it may slightly corrupt filesystem
184 (lost files, unbalanced directories). (I guess all filesystem may do it).
185
186 When compiled, you get warning: function declaration isn't a prototype. Does
187 anybody know what does it mean?
188
189
190 What does "unbalanced tree" message mean?
191 =========================================
192
193 Old versions of this driver created sometimes unbalanced dnode trees. OS/2
194 chkdsk doesn't scream if the tree is unbalanced (and sometimes creates
195 unbalanced trees too :-) but both HPFS and HPFS386 contain bug that it rarely
196 crashes when the tree is not balanced. This driver handles unbalanced trees
197 correctly and writes warning if it finds them. If you see this message, this is
198 probably because of directories created with old version of this driver.
199 Workaround is to move all files from that directory to another and then back
200 again. Do it in Linux, not OS/2! If you see this message in directory that is
201 whole created by this driver, it is BUG - let me know about it.
202
203
204 Bugs in OS/2
205 ============
206
207 When you have two (or more) lost directories pointing each to other, chkdsk
208 locks up when repairing filesystem.
209
210 Sometimes (I think it's random) when you create a file with one-char name under
211 OS/2, OS/2 marks it as 'long'. chkdsk then removes this flag saying "Minor fs
212 error corrected".
213
214 File names like "a .b" are marked as 'long' by OS/2 but chkdsk "corrects" it and
215 marks them as short (and writes "minor fs error corrected"). This bug is not in
216 HPFS386.
217
218 Codepage bugs described above
219 =============================
220
221 If you don't install fixpacks, there are many, many more...
222
223
224 History
225 =======
226
227 ====== =========================================================================
228 0.90 First public release
229 0.91 Fixed bug that caused shooting to memory when write_inode was called on
230 open inode (rarely happened)
231 0.92 Fixed a little memory leak in freeing directory inodes
232 0.93 Fixed bug that locked up the machine when there were too many filenames
233 with first 15 characters same
234 Fixed write_file to zero file when writing behind file end
235 0.94 Fixed a little memory leak when trying to delete busy file or directory
236 0.95 Fixed a bug that i_hpfs_parent_dir was not updated when moving files
237 1.90 First version for 2.1.1xx kernels
238 1.91 Fixed a bug that chk_sectors failed when sectors were at the end of disk
239 Fixed a race-condition when write_inode is called while deleting file
240 Fixed a bug that could possibly happen (with very low probability) when
241 using 0xff in filenames.
242
243 Rewritten locking to avoid race-conditions
244
245 Mount option 'eas' now works
246
247 Fsync no longer returns error
248
249 Files beginning with '.' are marked hidden
250
251 Remount support added
252
253 Alloc is not so slow when filesystem becomes full
254
255 Atimes are no more updated because it slows down operation
256
257 Code cleanup (removed all commented debug prints)
258 1.92 Corrected a bug when sync was called just before closing file
259 1.93 Modified, so that it works with kernels >= 2.1.131, I don't know if it
260 works with previous versions
261
262 Fixed a possible problem with disks > 64G (but I don't have one, so I can't
263 test it)
264
265 Fixed a file overflow at 2G
266
267 Added new option 'timeshift'
268
269 Changed behaviour on HPFS386: It is now possible to operate on HPFS386 in
270 read-only mode
271
272 Fixed a bug that slowed down alloc and prevented allocating 100% space
273 (this bug was not destructive)
274 1.94 Added workaround for one bug in Linux
275
276 Fixed one buffer leak
277
278 Fixed some incompatibilities with large extended attributes (but it's still
279 not 100% ok, I have no info on it and OS/2 doesn't want to create them)
280
281 Rewritten allocation
282
283 Fixed a bug with i_blocks (du sometimes didn't display correct values)
284
285 Directories have no longer archive attribute set (some programs don't like
286 it)
287
288 Fixed a bug that it set badly one flag in large anode tree (it was not
289 destructive)
290 1.95 Fixed one buffer leak, that could happen on corrupted filesystem
291
292 Fixed one bug in allocation in 1.94
293 1.96 Added workaround for one bug in OS/2 (HPFS locked up, HPFS386 reported
294 error sometimes when opening directories in PMSHELL)
295
296 Fixed a possible bitmap race
297
298 Fixed possible problem on large disks
299
300 You can now delete open files
301
302 Fixed a nondestructive race in rename
303 1.97 Support for HPFS v3 (on large partitions)
304
305 ZFixed a bug that it didn't allow creation of files > 128M
306 (it should be 2G)
307 1.97.1 Changed names of global symbols
308
309 Fixed a bug when chmoding or chowning root directory
310 1.98 Fixed a deadlock when using old_readdir
311 Better directory handling; workaround for "unbalanced tree" bug in OS/2
312 1.99 Corrected a possible problem when there's not enough space while deleting
313 file
314
315 Now it tries to truncate the file if there's not enough space when
316 deleting
317
318 Removed a lot of redundant code
319 2.00 Fixed a bug in rename (it was there since 1.96)
320 Better anti-fragmentation strategy
321 2.01 Fixed problem with directory listing over NFS
322
323 Directory lseek now checks for proper parameters
324
325 Fixed race-condition in buffer code - it is in all filesystems in Linux;
326 when reading device (cat /dev/hda) while creating files on it, files
327 could be damaged
328 2.02 Workaround for bug in breada in Linux. breada could cause accesses beyond
329 end of partition
330 2.03 Char, block devices and pipes are correctly created
331
332 Fixed non-crashing race in unlink (Alexander Viro)
333
334 Now it works with Japanese version of OS/2
335 2.04 Fixed error when ftruncate used to extend file
336 2.05 Fixed crash when got mount parameters without =
337
338 Fixed crash when allocation of anode failed due to full disk
339
340 Fixed some crashes when block io or inode allocation failed
341 2.06 Fixed some crash on corrupted disk structures
342
343 Better allocation strategy
344
345 Reschedule points added so that it doesn't lock CPU long time
346
347 It should work in read-only mode on Warp Server
348 2.07 More fixes for Warp Server. Now it really works
349 2.08 Creating new files is not so slow on large disks
350
351 An attempt to sync deleted file does not generate filesystem error
352 2.09 Fixed error on extremely fragmented files
353 ====== =========================================================================
354

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

HPFS 2.09 credits와 mount option

1-58

이 문서는 Mikulas Patocka가 1998~2004년에 작성한 Linux read/write HPFS 2.09 driver 설명입니다. 연락처는 `mikulas@artax.karlin.mff.cuni.cz`, homepage은 `https://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi`입니다.

Chris Smith의 1993년 original read-only HPFS에서 일부 code와 HPFS structure file을 가져왔습니다. Jacques Gelinas의 MSDOS mmap은 Jon Tombs가 1993년 8월 15일 작성한 `fs/nfs/mmap.c`에서 영감을 받았고, Werner Almesberger의 1992~1993년 MSDOS option parser와 CR/LF conversion도 기여했습니다.

`uid=xxx,gid=xxx,umask=xxx`는 extended attribute에 값이 없는 file의 owner, group, mode를 정합니다. default는 `uid=gid=0`과 system default umask입니다.

mode는 umask를 반전한 값입니다. 예를 들어 `umask 027`은 owner에게 모든 permission, group에게 read permission을 주고 그 밖의 user에게는 접근을 허용하지 않습니다. 일반 file mode는 추가로 `0666`과 AND되므로 executable 권한이 필요하면 extended attribute를 사용해야 합니다.

`case=lower,asis`는 `readdir`에서 filename을 lowercase로 바꿀지 정하며 default는 `asis`입니다.

`conv=binary,text,auto`는 CR/LF를 LF로 변환하는 방식이며 default는 `binary`입니다. `auto`는 source에 있는 text extension 목록으로 결정합니다.

원문 저자는 binary file 손상을 피하기 위해 text file을 변환하지 않는 편이 낫다고 설명하고, extension 목록 변경은 source에서 하라고 안내합니다. original read-only driver의 heuristic은 DJGPP binary처럼 앞부분에 짧은 text가 있는 file을 오판해 손상시킬 수 있어 제거했습니다.

`check=none,normal,strict`는 검사 수준이며 default는 `normal`입니다. `none`은 속도 향상이 작고 위험이 크며, `normal`은 손상된 filesystem에서도 crash하지 않도록 설계됐습니다. `strict`는 bitmap allocation 같은 추가 검사를 수행하는 debugging mode입니다.

`errors=continue,remount-ro,panic`은 filesystem error 발견 시 동작을 정하며 default는 `remount-ro`입니다.

`chkdsk=no,errors,always`는 OS/2가 검사하도록 filesystem을 dirty로 표시할 시점을 정하며 default는 `errors`입니다.

`eas=no,ro,rw`는 extended attribute 처리 방식이며 default는 `rw`입니다. `no`는 EA를 무시하고 항상 mount option의 UID/GID/mode를 사용합니다. `ro`는 EA를 읽되 만들지 않고, `rw`는 `chmod`, `chown`, `chgrp`, `mknod`, `ln -s` 사용 시 EA를 만듭니다.

`timeshift=(-)nnn`은 시간을 `nnn`초 이동하며 default는 0입니다. Linux에서 OS/2보다 시간이 한 시간 앞서 보이면 `timeshift=-3600`을 사용할 수 있습니다.

HPFS mount option
OptionDefault동작
`uid`, `gid`, `umask``uid=gid=0`, system umaskEA가 없는 file의 owner·group·mode
`case=lower,asis``asis``readdir` filename lowercase 여부
`conv=binary,text,auto``binary`CR/LF → LF conversion
`check=none,normal,strict``normal`filesystem consistency 검사 수준
`errors=continue,remount-ro,panic``remount-ro`filesystem error 대응
`chkdsk=no,errors,always``errors`OS/2 검사용 dirty 표시 시점
`eas=no,ro,rw``rw`extended attribute 무시·읽기·생성
`timeshift=(-)nnn``0`timestamp를 초 단위 이동

원문에 정의된 option 값, default와 동작입니다.

HPFS permission 결정
file의 `UID`·`GID`·`MODE` extended attribute 확인EA가 있으면 저장된 Unix-specific 값 사용EA가 없으면 mount의 `uid`·`gid`·`umask` 사용일반 file mode는 `0666`과 ANDexecutable permission은 EA로만 표현

EA 존재 여부와 mount default가 file의 Unix permission을 결정합니다.

.. SPDX-License-Identifier: GPL-2.0

====================
Read/Write HPFS 2.09
====================

1998-2004, Mikulas Patocka

:email: mikulas@artax.karlin.mff.cuni.cz
:homepage: https://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi

Credits
=======
Chris Smith, 1993, original read-only HPFS, some code and hpfs structures file
        is taken from it

Jacques Gelinas, MSDos mmap, Inspired by fs/nfs/mmap.c (Jon Tombs 15 Aug 1993)

Werner Almesberger, 1992, 1993, MSDos option parser & CR/LF conversion

Mount options

uid=xxx,gid=xxx,umask=xxx (default uid=gid=0 umask=default_system_umask)
        Set owner/group/mode for files that do not have it specified in extended
        attributes. Mode is inverted umask - for example umask 027 gives owner
        all permission, group read permission and anybody else no access. Note
        that for files mode is anded with 0666. If you want files to have 'x'
        rights, you must use extended attributes.
case=lower,asis (default asis)
        File name lowercasing in readdir.
conv=binary,text,auto (default binary)
        CR/LF -> LF conversion, if auto, decision is made according to extension
        - there is a list of text extensions (I thing it's better to not convert
        text file than to damage binary file). If you want to change that list,
        change it in the source. Original readonly HPFS contained some strange
        heuristic algorithm that I removed. I thing it's danger to let the
        computer decide whether file is text or binary. For example, DJGPP
        binaries contain small text message at the beginning and they could be
        misidentified and damaged under some circumstances.
check=none,normal,strict (default normal)
        Check level. Selecting none will cause only little speedup and big
        danger. I tried to write it so that it won't crash if check=normal on
        corrupted filesystems. check=strict means many superfluous checks -
        used for debugging (for example it checks if file is allocated in
        bitmaps when accessing it).
errors=continue,remount-ro,panic (default remount-ro)
        Behaviour when filesystem errors found.
chkdsk=no,errors,always (default errors)
        When to mark filesystem dirty so that OS/2 checks it.
eas=no,ro,rw (default rw)
        What to do with extended attributes. 'no' - ignore them and use always
        values specified in uid/gid/mode options. 'ro' - read extended
        attributes but do not create them. 'rw' - create extended attributes
        when you use chmod/chown/chgrp/mknod/ln -s on the filesystem.
timeshift=(-)nnn (default 0)
        Shifts the time by nnn seconds. For example, if you see under linux
        one hour more, than under os/2, use timeshift=-3600.

Codepage 처리와 혼합 언어 OS/2의 위험

114-140

HPFS volume에는 여러 codepage용 uppercasing table이 있을 수 있고 각 file은 filename이 속한 codepage를 가리킵니다. 하지만 원문 저자는 OS/2의 multiple codepage 구현이 매우 buggy하다고 설명합니다.

예시는 codepage 852를 쓰는 Czech OS/2 partition에 cp850을 쓰는 English OS/2로 boot하여 file을 만든 경우입니다. file은 codepage 850으로 올바르게 표시됐지만 Czech OS/2로 돌아오자 어떤 이름으로도 접근할 수 없었습니다.

추정 원인은 OS/2가 search pattern은 system codepage 852로 uppercase하고 비교 대상 filename은 file codepage 850으로 uppercase하여 두 값이 match하지 않는 것입니다.

같은 directory에 Czech OS/2로 새 file을 만들자 그 file도 접근할 수 없었습니다. HPFS directory는 filename 순서로 정렬돼야 하는데, file 배치용 uppercase와 검색용 uppercase 방법이 다른 것으로 보입니다.

PmShell에서 directory를 열면 crash했고 reboot 뒤에도 같은 directory를 다시 열려 했습니다. `chkdsk`는 오류를 무시했으며 low-level disk modification만 문제를 해결했습니다.

따라서 원문은 한 system에서 서로 다른 언어 version의 OS/2를 절대 섞지 말라고 경고합니다.

Linux driver는 복잡한 multiple codepage 지원이 OS/2 bug 때문에 이득보다 문제를 더 만들 것으로 보고, file의 codepage index와 무관하게 처음 찾은 codepage 하나로 uppercase와 lowercase를 수행합니다.

일반적으로 앞의 혼합 언어 시나리오를 만들지 않는 한 모든 filename은 그 첫 codepage에 있으므로 이 단순화가 동작합니다.

혼합 codepage 실패 사례
Czech OS/2 cp852의 HPFS partitionEnglish OS/2 cp850에서 새 file 생성file name codepage index는 850Czech OS/2가 search pattern을 cp852로 uppercasefile name은 cp850으로 uppercase되어 비교 실패directory 접근 불능·PmShell crash·chkdsk 미탐지

cp852 partition에 cp850 filename을 만든 뒤 lookup이 깨지는 과정입니다.

Linux HPFS codepage 정책
대상정책결과
HPFS volume처음 발견한 codepage 선택공통 uppercase/lowercase table
각 file codepage index무시혼합 codepage의 완전한 의미는 보존하지 않음
일반 단일 언어 volume대부분 첫 codepage와 일치통상적인 filename lookup 동작

OS/2의 복수 codepage 문제를 피하기 위한 단순화입니다.

Codepages
=========

HPFS can contain several uppercasing tables for several codepages and each
file has a pointer to codepage its name is in. However OS/2 was created in
America where people don't care much about codepages and so multiple codepages
support is quite buggy. I have Czech OS/2 working in codepage 852 on my disk.
Once I booted English OS/2 working in cp 850 and I created a file on my 852
partition. It marked file name codepage as 850 - good. But when I again booted
Czech OS/2, the file was completely inaccessible under any name. It seems that
OS/2 uppercases the search pattern with its system code page (852) and file
name it's comparing to with its code page (850). These could never match. Is it
really what IBM developers wanted? But problems continued. When I created in
Czech OS/2 another file in that directory, that file was inaccessible too. OS/2
probably uses different uppercasing method when searching where to place a file
(note, that files in HPFS directory must be sorted) and when searching for
a file. Finally when I opened this directory in PmShell, PmShell crashed (the
funny thing was that, when rebooted, PmShell tried to reopen this directory
again :-). chkdsk happily ignores these errors and only low-level disk
modification saved me.  Never mix different language versions of OS/2 on one
system although HPFS was designed to allow that.
OK, I could implement complex codepage support to this driver but I think it
would cause more problems than benefit with such buggy implementation in OS/2.
So this driver simply uses first codepage it finds for uppercasing and
lowercasing no matter what's file codepage index. Usually all file names are in
this codepage - if you don't try to do what I described above :-)

HPFS386와 알려진 driver 제약

141-188

OS/2 server의 HPFS386은 지원하지 않습니다. 일반 OS/2 client에 설치된 HPFS386은 동작해야 하지만 OS/2 server volume은 read-only mode로만 사용해야 합니다.

driver는 HPFS386 access control list나 extended permission list 구조를 처리하는 법, file 삭제 시 이를 제거하는 법, EA로 덮어쓰지 않는 법을 알지 못합니다. HPFS386 구조를 발견하면 read-only로 remount하여 파괴하지 않도록 시도합니다.

extended attribute 공간이 부족하면 EA가 truncate되지만 error가 반환되지 않습니다.

OS/2는 path가 약 256 character보다 길면 file에 접근하지 못하지만 이 driver는 긴 path 생성을 허용합니다. `chkdsk`도 이런 오류를 무시합니다.

매우 가득 찬 filesystem에서는 file 삭제가 `ENOSPC`로 실패할 수 있습니다. HPFS directory tree의 non-leaf dnode에 있는 file을 삭제할 때 다른 node로 교체해야 하는데, 새 filename이 더 길면 dnode에 맞지 않아 tree split과 추가 disk space가 필요하기 때문입니다.

workaround는 leaf file을 먼저 삭제하거나 file을 truncate해 공간을 만드는 것입니다. non-leaf일 확률은 약 1/50입니다.

이 문제는 directory가 매우 많아 preallocated directory band가 가득 찬 경우에만 발생하며 조건은 `number_of_directories / size_of_filesystem_in_mb > 4`입니다.

열린 directory는 삭제할 수 없고 directory 위로 rename할 수도 없습니다.

case만 바꾸는 rename은 driver가 지원하지만 VFS가 지원하지 않아 `mv file FILE`이 동작하지 않습니다.

성능상 모든 atime과 directory mtime을 갱신하지 않습니다. 갱신하도록 구현할 수 있지만 매우 느려집니다.

system이 memory와 swap을 모두 소진하면 lost file이나 unbalanced directory 같은 가벼운 filesystem corruption이 생길 수 있습니다.

compile 시 `function declaration isn't a prototype` warning이 발생한다는 역사적 메모도 원문에 포함돼 있습니다.

HPFS 알려진 제약
영역제약대응
HPFS386 serverACL·extended permission 미지원read-only 사용
EA 공간부족하면 error 없이 truncate충분한 여유 공간 유지
긴 pathOS/2가 약 256자 초과 접근 불가OS/2 호환 길이 유지
가득 찬 directory tree삭제가 `ENOSPC` 가능leaf 삭제 또는 file truncate
case-only renameVFS 제한으로 실패임시 이름을 거쳐 rename
atime·directory mtime성능상 갱신 안 함timestamp 의존 workflow 주의
memory+swap 고갈경미한 corruption 가능memory exhaustion 방지

지원 범위와 data integrity에 영향을 주는 주요 제한입니다.

가득 찬 filesystem의 삭제 실패
directory tree의 non-leaf file 삭제 요청다른 node로 entry 교체 필요교체 filename이 더 길어 dnode에 맞지 않음directory tree split 필요추가 disk space가 없어 `ENOSPC`leaf file 삭제 또는 file truncate로 공간 확보

non-leaf dnode 교체가 추가 공간을 요구하는 이유입니다.


Known bugs
==========

HPFS386 on OS/2 server is not supported. HPFS386 installed on normal OS/2 client
should work. If you have OS/2 server, use only read-only mode. I don't know how
to handle some HPFS386 structures like access control list or extended perm
list, I don't know how to delete them when file is deleted and how to not
overwrite them with extended attributes. Send me some info on these structures
and I'll make it. However, this driver should detect presence of HPFS386
structures, remount read-only and not destroy them (I hope).

When there's not enough space for extended attributes, they will be truncated
and no error is returned.

OS/2 can't access files if the path is longer than about 256 chars but this
driver allows you to do it. chkdsk ignores such errors.

Sometimes you won't be able to delete some files on a very full filesystem
(returning error ENOSPC). That's because file in non-leaf node in directory tree
(one directory, if it's large, has dirents in tree on HPFS) must be replaced
with another node when deleted. And that new file might have larger name than
the old one so the new name doesn't fit in directory node (dnode). And that
would result in directory tree splitting, that takes disk space. Workaround is
to delete other files that are leaf (probability that the file is non-leaf is
about 1/50) or to truncate file first to make some space.
You encounter this problem only if you have many directories so that
preallocated directory band is full i.e.::

        number_of_directories / size_of_filesystem_in_mb > 4.

You can't delete open directories.

You can't rename over directories (what is it good for?).

Renaming files so that only case changes doesn't work. This driver supports it
but vfs doesn't. Something like 'mv file FILE' won't work.

All atimes and directory mtimes are not updated. That's because of performance
reasons. If you extremely wish to update them, let me know, I'll write it (but
it will be slow).

When the system is out of memory and swap, it may slightly corrupt filesystem
(lost files, unbalanced directories). (I guess all filesystem may do it).

When compiled, you get warning: function declaration isn't a prototype. Does
anybody know what does it mean?

Unbalanced tree warning과 OS/2 bug

189-223

오래된 Linux HPFS driver는 때때로 unbalanced dnode tree를 만들었습니다. OS/2 `chkdsk`는 unbalanced tree를 오류로 보고하지 않고 스스로 만들기도 하지만, HPFS와 HPFS386에는 tree가 unbalanced일 때 드물게 crash하는 bug가 있습니다.

현재 driver는 unbalanced tree를 올바르게 처리하면서 발견 시 warning을 출력합니다. 보통 오래된 driver로 만든 directory가 원인입니다.

workaround는 해당 directory의 모든 file을 다른 곳으로 옮겼다가 다시 되돌리는 것입니다. 이 작업은 OS/2가 아니라 Linux에서 수행해야 합니다.

현재 driver가 전부 새로 만든 directory에서 warning이 나타나면 driver bug이므로 보고해야 합니다.

OS/2 자체의 bug도 기록돼 있습니다. 서로를 가리키는 lost directory가 둘 이상 있으면 `chkdsk`가 filesystem repair 중 lock up합니다.

OS/2에서 한 character 이름의 file을 만들면 때때로 무작위로 `long` flag가 설정되고, `chkdsk`는 `Minor fs error corrected`를 출력하며 flag를 제거합니다.

`a .b` 같은 filename도 OS/2가 `long`으로 표시하지만 `chkdsk`가 short로 바꿉니다. 이 bug은 HPFS386에는 없습니다.

앞서 설명한 codepage bug도 OS/2 bug에 포함되며 fixpack을 설치하지 않으면 더 많은 문제가 존재합니다.

Unbalanced tree 대응
상황의미조치
오래된 driver가 만든 directoryunbalanced dnode tree 가능Linux에서 file을 밖으로 이동 후 되돌림
현재 driver가 만든 directory새 driver bug 가능maintainer에게 보고
OS/2 `chkdsk`unbalanced tree를 경고하지 않거나 생성복구 작업을 Linux에서 수행

warning 원인과 안전한 복구 절차입니다.

원문에 기록된 OS/2 bug
Bug증상범위
순환 lost directory`chkdsk` repair lock-upOS/2
한 문자 filename무작위 `long` flag와 chkdsk 수정OS/2
`a .b` filename`long`을 `short`로 잘못 수정OS/2; HPFS386 제외
혼합 codepagelookup 실패·PmShell crash서로 다른 언어 OS/2
fixpack 미설치추가 bug 다수구형 OS/2

Linux driver 밖의 HPFS tool·OS 동작 문제입니다.


What does "unbalanced tree" message mean?
=========================================

Old versions of this driver created sometimes unbalanced dnode trees. OS/2
chkdsk doesn't scream if the tree is unbalanced (and sometimes creates
unbalanced trees too :-) but both HPFS and HPFS386 contain bug that it rarely
crashes when the tree is not balanced. This driver handles unbalanced trees
correctly and writes warning if it finds them. If you see this message, this is
probably because of directories created with old version of this driver.
Workaround is to move all files from that directory to another and then back
again. Do it in Linux, not OS/2! If you see this message in directory that is
whole created by this driver, it is BUG - let me know about it.


Bugs in OS/2
============

When you have two (or more) lost directories pointing each to other, chkdsk
locks up when repairing filesystem.

Sometimes (I think it's random) when you create a file with one-char name under
OS/2, OS/2 marks it as 'long'. chkdsk then removes this flag saying "Minor fs
error corrected".

File names like "a .b" are marked as 'long' by OS/2 but chkdsk "corrects" it and
marks them as short (and writes "minor fs error corrected"). This bug is not in
HPFS386.

Codepage bugs described above
=============================

If you don't install fixpacks, there are many, many more...

HPFS driver 0.90~2.09 history

224-353

이 절은 첫 public release인 0.90부터 extremely fragmented file 오류를 고친 2.09까지 Linux HPFS driver의 변경 history를 보존합니다.

HPFS history 0.90~1.90
Version변경사항
0.90첫 public release
0.91open inode에서 `write_inode` 호출 시 드물게 memory를 손상하던 bug 수정
0.92directory inode 해제 시 작은 memory leak 수정
0.93앞 15자가 같은 filename이 너무 많을 때 machine lock-up 수정; file 끝 뒤에 쓸 때 `write_file`이 file을 zeroing하도록 수정
0.94busy file·directory 삭제 시 작은 memory leak 수정
0.95file 이동 시 `i_hpfs_parent_dir`가 갱신되지 않던 bug 수정
1.902.1.1xx kernel용 첫 version

초기 read/write driver와 2.1.1xx kernel port까지의 변경입니다.

HPFS history 1.91~1.96
Version변경사항
1.91`chk_sectors`의 disk 끝 sector 검사, delete 중 `write_inode` race, filename의 `0xff` rare bug 수정; locking rewrite; `eas` option 활성화; `fsync` error 제거; dot file hidden 표시; remount 지원; full filesystem allocation 성능 개선; atime update 제거; debug code 정리
1.92file close 직전 sync 호출 bug 수정
1.93kernel 2.1.131 이상 지원; 64G 초과 disk 잠재 문제와 2G file overflow 수정; `timeshift` 추가; HPFS386 read-only operation 허용; 100% 공간 allocation을 막던 비파괴적 성능 bug 수정
1.94Linux bug workaround와 buffer leak 수정; large EA 호환성 일부 개선; allocation rewrite; `i_blocks`/`du` 값 수정; directory archive attribute 제거; large anode tree flag 수정
1.95손상 filesystem에서 가능한 buffer leak과 1.94 allocation bug 수정
1.96PmShell directory open 시 HPFS lock-up·HPFS386 error가 나던 OS/2 bug workaround; bitmap race·large disk 문제 수정; open file 삭제 지원; rename의 비파괴 race 수정

locking, EA, allocation, HPFS386 read-only와 race 수정입니다.

HPFS history 1.97~2.03
Version변경사항
1.97large partition용 HPFS v3 지원; 128M 초과 file 생성을 막던 bug 수정하여 2G까지 허용
1.97.1global symbol 이름 변경; root directory `chmod`·`chown` bug 수정
1.98`old_readdir` deadlock 수정; directory handling 개선; OS/2 unbalanced tree bug workaround
1.99file 삭제 중 공간 부족 문제 수정; 공간 부족 시 file truncate 시도; redundant code 제거
2.001.96부터 있던 rename bug 수정; anti-fragmentation strategy 개선
2.01NFS directory listing 수정; directory `lseek` parameter 검사; device를 읽으면서 file 생성 시 손상 가능하던 Linux filesystem 공통 buffer race 수정
2.02partition 끝 너머 접근을 일으킬 수 있던 Linux `breada` bug workaround
2.03character·block device와 pipe 생성 수정; unlink race 수정(Alexander Viro); Japanese OS/2 지원

대형 partition, directory, NFS와 device node 지원의 변화입니다.

HPFS history 2.04~2.09
Version변경사항
2.04`ftruncate`로 file 확장 시 error 수정
2.05`=` 없는 mount parameter, full disk의 anode allocation 실패, block I/O·inode allocation 실패 때의 crash 수정
2.06손상 disk structure crash 수정; allocation strategy 개선; CPU 장시간 lock 방지 reschedule point 추가; Warp Server read-only 동작 목표
2.07Warp Server 추가 수정으로 실제 동작
2.08large disk의 새 file 생성 성능 개선; 삭제된 file sync 시 filesystem error 제거
2.09극도로 fragmented된 file에서 발생하는 error 수정

allocation failure·Warp Server·대형 disk와 fragmentation 수정입니다.

HPFS driver 발전 방향
memory leak·race·deadlock과 corruption 방지allocation·large disk·large file 지원 개선EA·HPFS386·Warp Server·언어 version 호환성 확장directory·NFS·device node·rename VFS 동작 개선fragmentation과 full filesystem 성능·오류 처리 강화

history 전반의 변화가 모이는 네 축입니다.

History
=======

====== =========================================================================
0.90   First public release
0.91   Fixed bug that caused shooting to memory when write_inode was called on
       open inode (rarely happened)
0.92   Fixed a little memory leak in freeing directory inodes
0.93   Fixed bug that locked up the machine when there were too many filenames
       with first 15 characters same
       Fixed write_file to zero file when writing behind file end
0.94   Fixed a little memory leak when trying to delete busy file or directory
0.95   Fixed a bug that i_hpfs_parent_dir was not updated when moving files
1.90   First version for 2.1.1xx kernels
1.91   Fixed a bug that chk_sectors failed when sectors were at the end of disk
       Fixed a race-condition when write_inode is called while deleting file
       Fixed a bug that could possibly happen (with very low probability) when
       using 0xff in filenames.

       Rewritten locking to avoid race-conditions

       Mount option 'eas' now works

       Fsync no longer returns error

       Files beginning with '.' are marked hidden

       Remount support added

       Alloc is not so slow when filesystem becomes full

       Atimes are no more updated because it slows down operation

       Code cleanup (removed all commented debug prints)
1.92   Corrected a bug when sync was called just before closing file
1.93   Modified, so that it works with kernels >= 2.1.131, I don't know if it
       works with previous versions

       Fixed a possible problem with disks > 64G (but I don't have one, so I can't
       test it)

       Fixed a file overflow at 2G

       Added new option 'timeshift'

       Changed behaviour on HPFS386: It is now possible to operate on HPFS386 in
       read-only mode

       Fixed a bug that slowed down alloc and prevented allocating 100% space
       (this bug was not destructive)
1.94   Added workaround for one bug in Linux

       Fixed one buffer leak

       Fixed some incompatibilities with large extended attributes (but it's still
       not 100% ok, I have no info on it and OS/2 doesn't want to create them)

       Rewritten allocation

       Fixed a bug with i_blocks (du sometimes didn't display correct values)

       Directories have no longer archive attribute set (some programs don't like
       it)

       Fixed a bug that it set badly one flag in large anode tree (it was not
       destructive)
1.95   Fixed one buffer leak, that could happen on corrupted filesystem

       Fixed one bug in allocation in 1.94
1.96   Added workaround for one bug in OS/2 (HPFS locked up, HPFS386 reported
       error sometimes when opening directories in PMSHELL)

       Fixed a possible bitmap race

       Fixed possible problem on large disks

       You can now delete open files

       Fixed a nondestructive race in rename
1.97   Support for HPFS v3 (on large partitions)

       ZFixed a bug that it didn't allow creation of files > 128M
       (it should be 2G)
1.97.1 Changed names of global symbols

       Fixed a bug when chmoding or chowning root directory
1.98   Fixed a deadlock when using old_readdir
       Better directory handling; workaround for "unbalanced tree" bug in OS/2
1.99   Corrected a possible problem when there's not enough space while deleting
       file

       Now it tries to truncate the file if there's not enough space when
       deleting

       Removed a lot of redundant code
2.00   Fixed a bug in rename (it was there since 1.96)
       Better anti-fragmentation strategy
2.01   Fixed problem with directory listing over NFS

       Directory lseek now checks for proper parameters

       Fixed race-condition in buffer code - it is in all filesystems in Linux;
       when reading device (cat /dev/hda) while creating files on it, files
       could be damaged
2.02   Workaround for bug in breada in Linux. breada could cause accesses beyond
       end of partition
2.03   Char, block devices and pipes are correctly created

       Fixed non-crashing race in unlink (Alexander Viro)

       Now it works with Japanese version of OS/2
2.04   Fixed error when ftruncate used to extend file
2.05   Fixed crash when got mount parameters without =

       Fixed crash when allocation of anode failed due to full disk

       Fixed some crashes when block io or inode allocation failed
2.06   Fixed some crash on corrupted disk structures

       Better allocation strategy

       Reschedule points added so that it doesn't lock CPU long time

       It should work in read-only mode on Warp Server
2.07   More fixes for Warp Server. Now it really works
2.08   Creating new files is not so slow on large disks

       An attempt to sync deleted file does not generate filesystem error
2.09   Fixed error on extremely fragmented files
====== =========================================================================