讀取/寫入 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

修復了極度碎片化檔案上的錯誤