CMD 的 convert 命令如何能够在不丢失数据的情况下将 FAT 转换为 NTFS?

Has*_*ziz 5 windows ntfs filesystems cmd.exe filesystem-conversion

我一直想知道的事情。在 Windows 上,convert命令能够将 FAT16 或 FAT32 磁盘无损地转换为 NTFS(即不会丢失任何数据):

convert X: /fs:ntfs
Run Code Online (Sandbox Code Playgroud)

Windows 究竟如何做到这一点的技术细节是什么?在不擦除磁盘上的数据的情况下转换磁盘的文件系统有什么作用,并且将相同的原理应用于其他文件系统?

我知道 NTFS 是一个专有文件系统,所以细节可能只有 Microsoft 自己知道,但我想知道他们是否发布了任何关于此的文档,或者是否有其他人已经将 Windows/CMD 分开到足以找出答案。

以下问题讨论了exFAT 到 FAT32,但这是一个完全不同的问题,涉及完全不同的文件系统并且有完全不同的答案。

同样,我特别想知道convert为了转换磁盘的文件系统而不擦除其上的数据正在做什么,以及应用相同的原理是否适用于其他文件系统。

all*_*tic 8

首先,我想区分两个非常不同的事情:

  • Windows上的专有实现convert.exe如何处理FAT32 和 NTFS 之间的这种就地文件系统转换。
  • 一般来说,人们如何解决在两个文件系统之间进行转换的问题,就地,而没有 2 倍的可用磁盘空间,或者两个文件系统之间的可互操作元数据,或其他使问题变得微不足道的细节

对于第一个,我们主要受 Microsoft 的摆布来发布该信息,因为任何访问 Windows 源代码的人都必须签署 NDA。只有得到微软法律团队的批准,它才会被发布。当然,也许阅读这个问题的人得到了泄露的 Windows 源代码的非法副本,并从代码中找出了这一点,但这是一个合法的灰色区域。

所以我不会试图提供第一个问题的答案,因为我没有答案。

不过,我会回答第二个问题。

在文件系统的历史上,有很多情况是我们希望从一个文件系统升级到另一个文件系统而不擦除操作系统、重新安装或使用第二个磁盘。仅举几例:

  • 2017 年,每个将 Apple iOS 设备升级到 iOS 10.3 的人都在其 iDevice 的内置 NAND 上收到了从 HFS+ 到 APFS 的就地文件系统升级。
  • 多年来,btrfs 一直支持使用btrfs-convert工具将文件系统就地从 ext4 升级到 btrfs 。

开源fstransform程序旨在在许多不同的文件系统之间进行转换(有一些警告和限制)——它包括许多/最常见的 Linux 文件系统,以及令人印象深刻的 NTFS!尽管支持许多其他文件系统,但它还不支持 FAT32。

阅读其 C++ 代码将为您提供有关在不同文件系统之间转换所涉及的一般算法的最详细的技术知识,即使兼容性或互操作性不是由原始文件系统作者(源文件系统和目标文件系统)计划或设计的!)。

概括地说,一般过程是这样的:

  • 遍历当前文件系统的文件/目录树;并且,在现有文件系统内的一个新的普通文件中,根据当前文件系统的文件列表构造FS特定的文件表(文件列表、目录、符号链接、权限等),但采用新文件系统的格式.
  • 根据新文件系统的数据结构重新格式化旧文件系统的数据结构和就地元数据,并更新新文件表中的指针(指向逻辑磁盘块和偏移量,如适用)以指向重新计算的文件/directory/permission 块(使用诸如“inode”或“streams”之类的一般概念,这取决于您从哪个文件系统转换到它会有所不同)。
  • 在过程的最后,用新文件系统的元数据破坏性地覆盖原始文件系统的元数据(使用幻数等将文件系统标识为旧文件系统类型),并创建指向“超级块”的适当映射, “MFT”,或文件系统初始化自身所需的任何特定于文件系统的数据结构。
  • 如有必要,更新磁盘全局分区表(例如 MSDOS 格式或 GPT 格式),更新暗示分区中包含的文件系统类型的幻数(注意:某些文件系统共享相同的幻数,因为 AFAIK 它只是一个 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认同)

Ign*_*ams 7

关于convert的行为有几个提示:

对于从 FAT 或 FAT32 转换为 NTFS 的卷:
由于现有磁盘使用情况,MFT 是在与最初使用 NTFS 格式化的卷不同的位置创建的 [...] 例如,MFT 可能在转换后的卷上变得碎片化。

来源

  • Convert.exe 要求您在驱动器或分区上有一些可用空间来转换它。如果 Convert.exe 确定卷上没有足够的可用空间,它不会转换卷。

来源

从这些可以推测这是一个过程:

  1. 在空闲 FAT 块中的某处创建“人工”MFT,以免干扰现有的 FAT 或文件。
  2. 卷中的空闲 FAT 块将转换为 NTFS 块。
  3. 文件从 FAT 块移动到 NTFS 块,并从 FAT(s) 移动到 MFT。
  4. 重复第 2 步和第 3 步,直到所有文件都已转换完毕。
  5. 由 FAT(s) 占用的空间被转换为 NTFS 块。
  6. 分区的元数据被重写以指示该卷现在是 NTFS 而不是 FAT。