读取/写入 HPFS 2.09

1998-2004, Mikulas Patocka

电子邮件:

mikulas@artax.karlin.mff.cuni.cz

主页:

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

鸣谢

Chris Smith, 1993, 原始只读 HPFS,一些代码和 hpfs 结构文件

取自其中

Jacques Gelinas, MSDos mmap, 受 fs/nfs/mmap.c (Jon Tombs 15 Aug 1993) 启发

Werner Almesberger, 1992, 1993, MSDos 选项解析器 & CR/LF 转换

挂载选项

uid=xxx,gid=xxx,umask=xxx (默认 uid=gid=0 umask=default_system_umask)

为在扩展属性中未指定 owner/group/mode 的文件设置 owner/group/mode。Mode 是反转的 umask - 例如 umask 027 给予 owner 所有权限,group 读取权限,任何人都没有访问权限。请注意,对于文件,mode 会与 0666 进行与运算。如果您希望文件具有“x”权限,则必须使用扩展属性。

case=lower,asis (默认 asis)

在 readdir 中文件名小写。

conv=binary,text,auto (默认 binary)

CR/LF -> LF 转换,如果是 auto,则根据扩展名进行决策 - 有一个文本扩展名列表(我认为不转换文本文件比损坏二进制文件更好)。 如果你想改变这个列表,请在源代码中更改它。 原始的只读 HPFS 包含一些奇怪的启发式算法,我将其删除。 我认为让计算机决定文件是文本还是二进制是很危险的。 例如,DJGPP 二进制文件在开头包含一个小文本消息,在某些情况下可能会被错误识别和损坏。

check=none,normal,strict (默认 normal)

检查级别。 选择 none 只会导致少量加速和大危险。 我试图编写它,以便在损坏的文件系统上使用 check=normal 时不会崩溃。 check=strict 表示许多多余的检查 - 用于调试(例如,它检查文件是否在访问时在位图中分配)。

errors=continue,remount-ro,panic (默认 remount-ro)

发现文件系统错误时的行为。

chkdsk=no,errors,always (默认 errors)

何时标记文件系统为脏,以便 OS/2 检查它。

eas=no,ro,rw (默认 rw)

如何处理扩展属性。 ‘no’ - 忽略它们并始终使用在 uid/gid/mode 选项中指定的值。 ‘ro’ - 读取扩展属性但不创建它们。 ‘rw’ - 当您在文件系统上使用 chmod/chown/chgrp/mknod/ln -s 时创建扩展属性。

timeshift=(-)nnn (默认 0)

将时间移动 nnn 秒。 例如,如果您在 Linux 下看到比 OS/2 多一个小时,请使用 timeshift=-3600。

文件名

与 OS/2 中一样,文件名不区分大小写。 但是,shell 认为名称区分大小写,因此,例如,当您创建一个文件 FOO 时,您可以使用“cat FOO”、“cat Foo”、“cat foo”或“cat F*”,但不能使用“cat f*”。 请注意,您也无法在 HPFS 上编译 linux 内核(以及其他内容),因为内核会创建具有 bootsect.S 和 bootsect.s 等名称的不同文件。 搜索名称具有字符 >= 128 的文件时,会使用代码页 - 请参阅下文。 OS/2 忽略文件名末尾的点和空格,因此此驱动程序也这样做。 如果您创建“a. ...”,将创建文件“a”,但您仍然可以使用名称“a.”、“a..”、“a . . . “等访问它。

扩展属性

在 HPFS 分区上,OS/2 可以将称为扩展属性的特殊信息与每个文件关联。 扩展属性是 (key,value) 对,其中 key 是标识该属性的 ascii 字符串,value 是任意长度的可变字节字符串。 OS/2 在那里存储窗口和图标位置以及文件类型。 那么为什么不将其用于 unix 特定的信息,如文件所有者或访问权限? 此驱动程序可以做到这一点。 如果您在 hpfs 分区上 chown/chgrp/chmod,则会创建带有键“UID”、“GID”或“MODE”和 2 字节值的扩展属性。 仅创建与挂载选项中指定的默认值不同的扩展属性。 创建后,扩展属性永远不会被删除,它们只是被更改。 这意味着当您的默认 uid=0 并且您键入类似“chown luser file; chown root file”的内容时,该文件将包含扩展属性 UID=0。 当您卸载 fs 并使用 uid=luser_uid 再次挂载它时,该文件仍然归 root 所有! 如果您将文件 chmod 为 444,则不会设置扩展属性“MODE”,此特殊情况是通过设置只读标志来完成的。 当您 mknod 一个块或字符设备时,除了“MODE”之外,还会创建一个特殊的 4 字节扩展属性“DEV”,其中包含设备号。 目前,此驱动程序无法调整扩展属性的大小 - 这意味着如果有人(我不知道是谁?)已设置大小不同的“UID”、“GID”、“MODE”或“DEV”属性,它们将不会被重写并且更改这些值不起作用。

代码页

HPFS 可以包含用于多个代码页的多个大写表,每个文件都有一个指向其名称所在的代码页的指针。 然而,OS/2 是在美国创建的,那里的人们不太关心代码页,因此对多个代码页的支持非常错误。 我在我的磁盘上有在代码页 852 中工作的捷克 OS/2。 我曾经启动过在 cp 850 中工作的英语 OS/2,并在我的 852 分区上创建了一个文件。 它将文件名代码页标记为 850 - 很好。 但是当我再次启动捷克 OS/2 时,该文件在任何名称下都完全无法访问。 看来 OS/2 使用其系统代码页 (852) 对搜索模式进行大写,并使用其代码页 (850) 对其比较的文件名进行大写。 这些永远无法匹配。 这真的是 IBM 开发人员想要的吗? 但问题仍在继续。 当我在捷克 OS/2 中在该目录中创建另一个文件时,该文件也无法访问。 OS/2 可能在使用不同的方法对搜索模式进行大写,以确定将文件放置在哪里(请注意,HPFS 目录中的文件必须排序)以及搜索文件时。 最后,当我在 PmShell 中打开此目录时,PmShell 崩溃了(有趣的是,重新启动后,PmShell 试图再次重新打开此目录 :-))。 chkdsk 愉快地忽略了这些错误,只有低级磁盘修改才能拯救我。 永远不要在一个系统上混合使用不同语言版本的 OS/2,尽管 HPFS 旨在允许这样做。 好的,我可以为该驱动程序实现复杂的代码页支持,但我认为它会在 OS/2 中出现如此错误的实现时导致更多问题而不是好处。 因此,无论文件代码页索引如何,此驱动程序都只使用找到的第一个代码页来进行大写和小写转换。 通常所有文件名都在此代码页中 - 如果您不尝试执行我上面描述的操作 :-)

已知错误

不支持 OS/2 服务器上的 HPFS386。 安装在普通 OS/2 客户端上的 HPFS386 应该可以工作。 如果您有 OS/2 服务器,请仅使用只读模式。 我不知道如何处理某些 HPFS386 结构,例如访问控制列表或扩展权限列表,我不知道如何在删除文件时删除它们以及如何不使用扩展属性覆盖它们。 向我发送一些关于这些结构的信息,我会完成它。 但是,此驱动程序应检测到 HPFS386 结构的存在,以只读方式重新挂载并且不会破坏它们(我希望如此)。

当没有足够的空间用于扩展属性时,它们将被截断并且不会返回错误。

如果路径长于约 256 个字符,则 OS/2 无法访问文件,但此驱动程序允许您执行此操作。 chkdsk 忽略此类错误。

有时您将无法删除非常完整的文件系统上的某些文件(返回错误 ENOSPC)。 这是因为目录树中非叶节点中的文件(如果目录很大,则一个目录在 HPFS 上具有树中的 dirents)在删除时必须替换为另一个节点。 并且该新文件可能比旧文件具有更大的名称,因此新名称不适合目录节点 (dnode)。 这将导致目录树拆分,从而占用磁盘空间。 解决方法是删除其他叶文件(文件是非叶的概率约为 1/50)或先截断文件以腾出一些空间。 仅当您有许多目录以至于预先分配的目录带已满时,才会遇到此问题,即

number_of_directories / size_of_filesystem_in_mb > 4.

您无法删除打开的目录。

您无法重命名到目录上(这有什么好处?)。

重命名文件以仅更改大小写不起作用。 此驱动程序支持它,但 vfs 不支持。 类似“mv file FILE”的操作将不起作用。

所有 atimes 和目录 mtimes 都没有更新。 这是出于性能原因。 如果您非常希望更新它们,请告诉我,我会编写它(但它会很慢)。

当系统内存和交换空间不足时,可能会稍微损坏文件系统(丢失文件、不平衡的目录)。 (我猜所有文件系统都可能这样做)。

编译时,您会收到警告:函数声明不是原型。 有人知道它是什么意思吗?

“不平衡树”消息是什么意思?

此驱动程序的旧版本有时会创建不平衡的 dnode 树。 如果树不平衡,OS/2 chkdsk 不会尖叫(有时也会创建不平衡的树 :-),但 HPFS 和 HPFS386 都包含一个错误,即当树不平衡时,它很少崩溃。 此驱动程序可以正确处理不平衡的树,如果发现它们,则会写入警告。 如果您看到此消息,则可能是因为使用此驱动程序的旧版本创建的目录。 解决方法是将该目录中的所有文件移动到另一个目录,然后再返回。 在 Linux 中执行此操作,而不是在 OS/2 中! 如果您在此驱动程序完全创建的目录中看到此消息,则这是错误 - 请告诉我。

OS/2 中的错误

当您有两个(或更多)丢失的目录相互指向时,chkdsk 在修复文件系统时会锁定。

有时(我认为它是随机的),当您在 OS/2 下创建一个具有单字符名称的文件时,OS/2 会将其标记为“长”。 chkdsk 然后删除此标志,并说“已更正次要 fs 错误”。

类似“a .b”的文件名被 OS/2 标记为“长”,但 chkdsk“更正”它并将它们标记为短(并写入“已更正次要 fs 错误”)。 HPFS386 中没有此错误。

上面描述的代码页错误

如果您不安装修补程序,则会有很多很多...

历史记录

0.90

首次公开发布

0.91

修复了在打开的 inode 上调用 write_inode 时导致射入内存的错误(很少发生)

0.92

修复了释放目录 inode 时的小内存泄漏

0.93

修复了在太多文件名的前 15 个字符相同时锁定机器的错误修复了在写入文件结尾后将文件归零的 write_file

0.94

修复了尝试删除繁忙文件或目录时的小内存泄漏

0.95

修复了移动文件时 i_hpfs_parent_dir 未更新的错误

1.90

2.1.1xx 内核的第一个版本

1.91

修复了当扇区位于磁盘末尾时 chk_sectors 失败的错误修复了在删除文件时调用 write_inode 时发生的竞争条件修复了在使用文件名中的 0xff 时可能发生的错误(概率非常低)。

重写锁定以避免竞争条件

挂载选项“eas”现在可以使用

Fsync 不再返回错误

以“.”开头的文件标记为隐藏

添加了重新挂载支持

当文件系统已满时,分配速度不会那么慢

Atimes 不再更新,因为它会减慢操作速度

代码清理(删除了所有注释的调试打印)

1.92

更正了在关闭文件之前调用 sync 时出现的错误

1.93

已修改,以便它可以与 >= 2.1.131 的内核一起使用,我不知道它是否可以与以前的版本一起使用

修复了磁盘 > 64G 可能出现的问题(但我没有一个,所以我无法测试它)

修复了 2G 处的文件溢出

添加了新选项“timeshift”

更改了 HPFS386 上的行为:现在可以在只读模式下在 HPFS386 上操作

修复了一个减慢分配速度并阻止分配 100% 空间的错误(此错误不是破坏性的)

1.94

添加了针对 Linux 中的一个错误的解决方法

修复了一个缓冲区泄漏

修复了一些与大型扩展属性不兼容的问题(但仍然不是 100% 可以,我没有相关信息并且 OS/2 不想创建它们)

重写分配

修复了 i_blocks 的错误(du 有时不会显示正确的值)

目录不再设置存档属性(某些程序不喜欢它)

修复了一个错误,它在大型阳极树中错误地设置了一个标志(它不是破坏性的)

1.95

修复了一个缓冲区泄漏,它可能发生在损坏的文件系统上

修复了 1.94 中分配的一个错误

1.96

添加了针对 OS/2 中的一个错误的解决方法(在 PMSHELL 中打开目录时,HPFS 锁定,HPFS386 有时报告错误)

修复了可能出现的位图竞争

修复了大型磁盘上可能出现的问题

您现在可以删除打开的文件

修复了重命名中的非破坏性竞争

1.97

支持 HPFS v3(在大型分区上)

修复了一个错误,它不允许创建 > 128M 的文件(应该是 2G)

1.97.1

更改了全局符号的名称

修复了 chmod 或 chown 根目录时的错误

1.98

修复了使用 old_readdir 时发生的死锁更好的目录处理; 针对 OS/2 中的“不平衡树”错误的解决方法

1.99

更正了删除文件时空间不足可能出现的问题

现在,如果没有足够的空间,它会尝试截断文件

删除了许多冗余代码

2.00

修复了重命名中的一个错误(自 1.96 以来一直存在)更好的反碎片策略

2.01

修复了通过 NFS 进行目录列表的问题

目录 lseek 现在检查正确的参数

修复了缓冲区代码中的竞争条件 - 它在 Linux 中的所有文件系统中; 在设备上创建文件时读取设备 (cat /dev/hda) 可能会损坏文件

2.02

针对 Linux 中的 breada 错误的解决方法。 breada 可能会导致访问超出分区末尾

2.03

正确创建字符、块设备和管道

修复了取消链接中的非崩溃竞争(Alexander Viro)

现在它可以与日语版本的 OS/2 一起使用

2.04

修复了用于扩展文件时 ftruncate 出现的错误

2.05

修复了在没有 = 的情况下获取挂载参数时发生的崩溃

修复了由于磁盘已满而导致阳极分配失败时发生的崩溃

修复了一些由于块 io 或 inode 分配失败而导致的崩溃

2.06

修复了一些由于损坏的磁盘结构而导致的崩溃

更好的分配策略

添加了重新调度点,以便它不会长时间锁定 CPU

它应该可以在 Warp Server 上以只读模式工作

2.07

更多针对 Warp Server 的修复。 现在它真的有效了

2.08

在大型磁盘上创建新文件不会那么慢

尝试同步已删除的文件不会生成文件系统错误

2.09

修复了极度碎片化文件上的错误