我一直在想这个问题。在 Windows 上,转变命令能够将 FAT16 或 FAT32 磁盘非破坏性地转换为 NTFS(即不会丢失任何数据):
convert X: /fs:ntfs
什么是技术细节Windows 究竟是如何做到这一点的?它是如何转换磁盘的文件系统而不擦除其上的数据的?同样的原理是否适用于其他文件系统?
我知道 NTFS 是一个专有文件系统,因此可能只有微软自己才知道详细信息,但我想知道他们是否发布过有关此内容的任何文档,或者是否有其他人对 Windows/CMD 进行过深入研究以找出答案。
以下问题讨论的是exFAT 到 FAT32,但这是一个完全不同的问题,涉及完全不同的文件系统,并且有完全不同的答案。
再次,我特别想知道如何convert
才能在不擦除磁盘数据的情况下转换磁盘的文件系统,以及是否将相同的原理应用于其他文件系统。
答案1
首先我想区分两件截然不同的事情:
- 如何
convert.exe
在 Windows 上实施专有负责 FAT32 和 NTFS 之间的就地文件系统转换。 - 一般来说,如何解决在两个文件系统之间进行转换的问题,在没有 2 倍所需磁盘空间可用的情况下,或者在两个文件系统之间没有可互操作的元数据的情况下,或者在没有其他类似细节的情况下,使问题变得简单
对于第一个问题,我们主要依靠微软来发布这些信息,因为任何能够访问 Windows 源代码的人都必须签署保密协议。只有获得微软法律团队的批准,这些信息才会被发布。当然,也许阅读这个问题的人非法获得了泄露的 Windows 源代码,并从代码中发现了这一点,但这是一个法律灰色地带。
因此我不会尝试回答第一个问题,因为我没有答案。
不过,我会回答第二个问题。
在文件系统的发展历史中,有很多情况下,我们希望从一个文件系统升级到另一个文件系统,而无需清除操作系统、重新安装或使用第二个磁盘。举几个例子:
- 2017年,每个人将 Apple iOS 设备升级到 iOS 10.3 后,其 iDevice 内置 NAND 上的文件系统就地从 HFS+ 升级到 APFS。
- 多年来,btrfs 一直支持使用以下方式将文件系统从 ext4 升级到 btrfs:btrfs-转换工具。
开源函数变换程序旨在在许多不同的文件系统(有一些注意事项和限制)——它包括许多/最常见的 Linux 文件系统,以及令人印象深刻的 NTFS!尽管支持许多其他文件系统,但它尚不支持 FAT32。
阅读其 C++ 代码将为您提供有关在不同文件系统之间进行转换的一般算法的最详细的技术知识,即使兼容性或互操作性不是由原始文件系统作者(无论是源文件系统还是目标文件系统!)计划或设计的。
总体来说,其流程大致如下:
- 遍历当前文件系统的文件/目录树;然后,在新的普通文件在现有文件系统中,根据当前文件系统的文件列表构建特定于文件系统的文件表(文件、目录、符号链接、权限等的列表),但在新的文件系统的格式。
- 根据新文件系统的数据结构重新格式化旧文件系统的数据结构和就地元数据,并更新新文件表中的指针(指向逻辑磁盘块和偏移量,如适用)以指向重新计算的文件/目录/权限块(使用诸如“inodes”或“流”之类的一般概念,具体取决于您要从/向哪个文件系统转换)。
- 在该过程的最后,用新文件系统的元数据破坏性地覆盖原始文件系统的元数据(使用魔术数字等将文件系统标识为旧文件系统类型),并创建指向“超级块”、“MFT”或文件系统初始化所需的任何特定于文件系统的数据结构的适当映射。
- 更新磁盘全局分区表(例如 MSDOS 格式或 GPT 格式)更新暗示分区内包含的文件系统类型的魔数,如果有必要(注意:某些文件系统共享相同的魔法数字,因为据我所知它只是一个 16 位数字,所以只有 65,535 种可能性。并且一些文件系统驱动程序足够智能,可以忽略魔法数字并“探测”文件系统的实际数据结构以确定该分区是否包含给定文件系统的实例。)
值得注意的是,至少最后两个步骤是非原子;这意味着,日志文件系统(如 NTFS、reiserfs、XFS、zfs 等)通常的原子性保证不可用。如果系统崩溃、关闭,或者即使执行转换的用户空间程序在此过程中崩溃或挂起,文件系统将需要数据恢复专家来恢复数据或恢复文件系统(旧的或新的)的健全性。在这些“破坏性”操作期间,底层存储介质正在以文件系统日志不支持的方式对关键数据进行破坏性覆盖,因为该过程本质上绕过了旧文件系统的日志(为了从一个 FS 更改为另一个,您不能告诉旧文件系统通过用它不知道的其他东西覆盖其核心元数据来“安全地自杀”)。
相比之下,要求执行数据日志记录的文件系统执行普通的事实上,写入是原子的:要么整个写入完成,要么根本没有完成(如果系统在写入过程中崩溃,则可以回滚对日志区域的未完成的部分写入,这是系统 BSOD 或内核崩溃后程序在启动时所做的事情fsck
。chkdsk
)
进行就地 FS 转换非常危险 - 它与 BIOS 刷新一样危险(在移动设备上尤其如此,因为无法启动操作系统可能会导致设备永久变砖),因为许多操作的安全性无法保证,并且往往需要很长时间才能完成,因此用户很有可能认为操作系统已挂起并在转换过程中对其进行电源循环,或者电池供电设备的电池耗尽。
欲了解如何做到这一点更安全在两个文件系统的默契配合下设计要将两者进行转换(据我所知,iOS 上的 HFS+ 到 APFS 转换就是这样的),精彩的谈话采用法医方法来查明 APFS 到底发生了什么。它不直接解决转换问题,但可以从提供的信息推断出有关转换的一些细节。
这就是说,对于你最初的问题,可能永远找不到一个明确的答案,但我认为,提供大量关于就地 FS 转换的一般过程的知识,应该能给你足够的线索,让你解开什么是可能是 的过程convert.exe
。
顺便说一句,我原本以为“哦,太好了,ReactOS 已经实现了这个工具,我们只需查看源代码就可以了!”——没有。他们没有在 ReactOS 上公开实现 convert.exe。如果任何用户在他们的系统上使用过它,他们一定是在执行专有的 MS Windows 二进制文件。否则我猜他们只是没有在 ReactOS 中提供这个实用程序。
答案2
convert
关于的行为,有几点提示:
对于从 FAT 或 FAT32 转换为 NTFS 的卷:
由于现有的磁盘使用情况,MFT 的创建位置与最初使用 NTFS 格式化的卷的位置不同 [...] 例如,MFT 可能会在转换后的卷上变得碎片化。
- Convert.exe 要求驱动器或分区上有一些可用空间才能进行转换。如果 Convert.exe 确定卷上没有足够的可用空间,则不会转换该卷。
由此可以推测过程如下:
- 在空闲的 FAT 块中的某个地方创建一个“人工” MFT,以便不干扰现有的 FAT 或文件。
- 卷中的空闲 FAT 块被转换为 NTFS 块。
- 文件从 FAT 块移动到 NTFS 块,再从 FAT 移动到 MFT。
- 重复步骤 2 和 3,直到所有文件都转换完毕。
- FAT 占用的空间被转换为 NTFS 块。
- 分区的元数据被重写以表明该卷现在是 NTFS 而不是 FAT。