【问题标题】:Can I write a file to a specific cluster location?我可以将文件写入特定的集群位置吗?
【发布时间】:2021-06-06 21:17:01
【问题描述】:

您知道,当应用程序打开文件并对其进行写入时,系统会选择将存储在哪个集群中。我要选择自己!让我告诉你我真正想做的事……其实我并不一定想写任何东西。我有一个 HDD,中间有一个坏范围的集群,我想将该空间标记为它被文件占用,并最终将其设置为隐藏的不可移动系统(如 Windows 中的页面文件),以便它将不再被访问。关于如何做到这一点的任何想法?

后期编辑: 我认为THIS 是我最后的希望。我刚刚找到它,但我需要调查......也许可以在任何地方创建一个文件,然后重新定位到所需的集群。但这需要编写,如果集群不好,函数可能会失败。

【问题讨论】:

  • 这是一个非常底层的操作。最好不要自己做,把它留给专门的恢复工具。
  • 我还没有遇到能够完成这项工作的恢复工具,但是......
  • SpinRite 可以从坏集群中恢复数据,并将其标记为不可写。
  • 为什么您认为将某些文件写入此类扇区可以解决您的问题?现代操作系统以定期检查每个文件的内容而闻名,并且默认情况下还对每个驱动器执行自动碎片整理。这意味着即使您将文件写入某个集群,也不能保证该文件会保留在那里。正如其他人建议的那样,解决问题的正确方法是运行某种磁盘扫描实用程序,该实用程序能够将某些集群标记为坏,从而防止任何程序将任何数据写入此类集群。
  • PS:我什至见过允许您手动将某些磁盘集群设置为坏的磁盘实用程序,即使您实际上这样的集群可能非常好。我什至听说过一些计算机病毒将某些集群标记为不良然后隐藏在其中。

标签: delphi filesystems ioctl delphi-10.3-rio disk-io


【解决方案1】:

我相信对于您的具体问题:“我可以将文件写入特定集群位置”的答案通常是“否”。

原因是现代操作系统的体系结构是分层的,因此底层磁盘存储的访问级别低于您可以访问的级别,当然磁盘可以以不同的方式格式化,因此会有不同的内核支持不同格式的模式驱动程序。即便如此,智能磁盘控制器仍然可以重新映射内核模式驱动程序使用的地址。简而言之,可能的重定向级别太多,无法确保您的干预发生在正确的级别。

如果您谈论的是 Windows(您没有说明但似乎是假设的),那么您需要查看内核中的存储驱动程序(请参阅 https://docs.microsoft.com/en-us/windows-hardware/drivers/storage/)。我认为最接近您可以合理地编写自己的可安装文件系统驱动程序(请参阅https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/_ifsk/)。这实际上是一个“过滤器”,因为它位于 IO 请求链中,可以拦截和更改 IO 请求包 (IRP)。当然,这将在内核中运行,而不是在用户空间中,通常这将用 C 编写,我注意到您的问题已标记为 Delphi。

您的 IFS 驱动程序可以位于请求链中的不同级别。我已经使用这种技术来拦截对特定文件系统位置(路径/文件名)的调用并更改 IRP 以虚拟化请求 - 甚至从内核回调用户空间以解决应如何处理请求。使用提供的示例通过 IFS 驱动程序实现基本功能并不太涉及,因为它是一个过滤器,而不是一个完整的存储系统。

但是,这种方法的本质意味着另一个过滤器也可以改变您在驱动程序中所做的事情。

您可以考虑更换与硬件接口的文件系统驱动程序,但我认为在这种情况下这可能是一项过多的任务......正如@fpiette 已经指出的那样,磁盘控制器硬件可以重新映射您的请求无论如何。

在 MSDOS 时代,对硬件的访问更加简单,并且由 BIOS 提供,可以挂钩以允许拦截请求。现代环境不再那么简单了。 IFS 方法确实允许挂钩 IO,但它不能提供您需要的控制级别。

编辑关于 OP 建议使用 FSCTL_MOVE_FILE

对于简单的环境,这可能会满足您的需求,它旨在支持碎片整理过程。

但是我仍然认为不能保证这实际上会做你想做的事。

您会从链接到它的页面中注意到,它正在将文件的一个或多个虚拟集群从一个逻辑集群移动到同一卷内的另一个逻辑集群

这是一个传递给我上面提到的底层存储驱动程序的代码。存储层做什么取决于存储层,将取决于底层技术。使用更高级的存储,无法保证这实际上解决了我认为您的问题所询问的物理位置。

但这完全取决于底层存储系统。对于操作系统的某些类型的存储重定位,可能不会以相同的方式进行处理。例如,考虑具有内置数据分层功能的企业存储阵列。在不了解操作系统的情况下,数据将根据分层算法在存储中重新定位。还要考虑到允许直接访问数据的技术(如 NVMe),并且您正在使用“虚拟”和“逻辑”集群,而不是物理位置。

但是,您可能会发现,在一个简单的情况下,只要支持底层驱动程序并且在操作系统和内核之外不进行重新映射,这就可以满足您的需要。

【讨论】:

  • 磁盘控制器硬件没有重新映射任何东西...我制作了一个应用程序来读取错误的确切集群。我看了很多遍……每次都失败了,那个“智能超智能驱动器”并没有重新映射任何东西!我应该做些什么来说服它重新映射那个不幸的悲惨集群?!如果它看到它不能再被读取,它到底在等什么?当然,这些都是反问......控制器只是愚蠢的。
  • @MarusNebunu 磁盘控制器可以是各种各样的东西——光纤通道 HBA 适配器、SCSI RAID 控制器等,当然你也可以在 VM 中运行。通常有一个“逻辑地址”,实际硬件可以映射到您要访问的硬件,但不能保证它访问的实际物理位置。高端存储可以在不同磁盘和磁盘阵列之间物理迁移数据,而操作系统不会意识到它正在发生。
  • 关于编辑...我只想为自己的系统制作一个应用程序,一台普通的笔记本电脑和一个普通的硬盘。我写软件只是为了我的需要。我不打算让这个代码在这个世界上的每台计算机上都有效。我有一个简单的硬盘驱动器,没有启用自动碎片整理。我读取了该磁盘的每个扇区,并用无法访问的扇区制作了一张地图。如果我可以在那里创建一些文件,那么该空间将无法再次访问。这只是一个临时解决方案。它不必是完美的。不幸的是,我的技能还没有那么高,以至于我可以编写驱动程序。
  • @MarusNebunu 我认为对于一个简单的案例,您的想法可能会给您带来一些吸引力,但是通过阅读我对如何使用该功能所做的阅读,我找不到解决问题的“保证”被呈现。您可能会发现它适用于您的情况......但您需要小心,如果它磨损了,您几乎肯定会损坏您的文件。如果您有一个可以丢弃的测试环境,那么我认为 ti 将是一个非常有趣的项目。
【解决方案2】:

由于你的问题是标记坏簇,你不需要编写任何程序。使用 Windows 提供的命令行实用程序CHKDSK

我是提升的命令提示符(以管理员身份运行),运行命令:

chkdsk /r c:

检查将在下次重新启动时完成。

别忘了阅读documentation

【讨论】:

  • 标记坏集群可能是个问题,但在这里,在这个问题中,问题是如何标记它在该区域创建文件。 Chkdsk 不标记任何内容。事实上,我认为在今天的 Windows 中没有标记坏集群这样的事情。唯一真正标记坏集群的应用程序是 MS-DOS 时代 Norton Utilities 中的 ScanDisk...
  • IMO 你错了,chkdsk 检测并标记坏集群,因此它们将不再被任何文件使用。您必须为此使用 /r 命令行选项。另请注意,现代磁盘是智能的,并且具有将坏扇区映射到好扇区的内部重新映射功能。一旦磁盘耗尽了他的列表或备用扇区,您只会在 Windows 级别看到一个坏扇区。然后是时候更换磁盘了,因为它已经有一堆坏扇区:它快死了。
  • 对于某些品牌的磁盘,有与磁盘固件交互的低级软件,您可以真正重新格式化它(对于那些磁盘,Windows格式并不能真正在低级格式化,它只是构建文件系统结构)。您说的是哪个磁盘品牌和型号?
  • 这个话题最好在superuser.com(一个 StackOverflow 并行站点)中讨论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 2013-12-06
  • 1970-01-01
  • 2011-01-11
  • 2022-11-30
  • 1970-01-01
  • 2012-06-12
相关资源
最近更新 更多