如何判断零是源自修剪还是来自 SSD 上实际写入零

如何判断零是源自修剪还是来自 SSD 上实际写入零

假设我将零写入驱动器的某个 LBA 范围,然后我会修剪这些逻辑块(例如,使用 blkdiscard 甚至 hdparm)。鉴于驱动器具有“修剪后读取零”行为,是否有办法判断逻辑块是否经过修剪?

(我能想到的一种可能有效的方法是定时读取,以检测修剪数据块上的响应比全零的未修剪数据块上的响应更快,但这个问题更多的是关于询问磁盘的 API。)

答案1

首先,trim 不用于将块归零。Trim 用于告诉 SSD 不再需要某个块,可以丢弃其内容。trim 的目的实际上是通过告诉 SSD 可以自由重写块而无需先保留其内容来帮助 SSD 进行写入均衡。因此,先将块归零并不需要额外的步骤。

SSD 修剪标准规定,读取修剪后的块将产生未定义的结果,而不是零块,尽管某些版本的标准确实包含“修剪后读取零”版本的修剪。由于读取修剪后的块具有未定义的行为,即使忽略缓存问题,您也不太可能通过计时读取来判断块是否修剪过。写入修剪后的块可能也没有时间差异,因为写入均衡可能会导致写入不同的物理块。

由于 trim 旨在丢弃块,因此文件系统不会对文件中的块使用 trim——而只会对从文件中释放的块使用 trim。因此,询问是否有办法判断文件中的块是否已被修剪是没有意义的,因为文件系统不会对文件执行此操作。如果您的文件系统中有已修剪的块,则文件系统很可能已损坏。即使您确实有这样一个损坏的文件系统,trim 标准也不包括任何查询块是否已修剪或 SSD 上有多少块已修剪的方法。更好的问题是询问是否有办法确定文件中的块是否已损坏。某些文件系统(例如 zfs 等)确实具有此功能,但它可能无法在文件系统内部之外直接访问。在 RAID 中,在读取损坏的块时,raid可能记录此事件,但也会重建块并可能在其位置重写一个好块。如果失败,假设 RAID 不只是脱机,它可能会返回 I/O 错误。

但是,如果您的文件系统实际上是另一个文件系统中的文件的文件系统映像,则 fstrim 可以告诉操作系统释放空闲块,这会导致底层文件系统在文件系统映像文件中实际创建空洞。与 SSD 上的 trim 不同,文件中空洞的行为定义非常明确,并且始终返回零。还有一些(有点不可移植的)系统调用,允许程序询问文件系统文件中的空洞在哪里。

答案2

我认为你应该以更好的方式提出问题,根本不涉及文件或文件系统,因为这似乎是你真正感兴趣的:

假设我将零写入驱动器的某个 LBA 范围,然后我会 TRIM 这些逻辑块(例如,使用blkdiscard 或甚至hdparm)。鉴于驱动器具有TRIM之后读取零行为,有没有办法让人分辨出逻辑块是否被TRIM了?

而答案(来自我)是,除非供应商提供一些特定于供应商的方法来检查逻辑块到实际存储的映射,或者你设法通过某种方式破解控制器来做等效的事情,否则,在通用协议/命令集中没有标准的方法来告诉别人可靠地

答案3

对于 NVME 磁盘,有一种东西叫做杜尔贝, 或者释放或未写入的逻辑块错误。以下是章节3.2.3.2.1 已释放或未写入的逻辑块NVM Express® NVM 命令集规范修订版 1.0c 2022 年 10 月 3 日

使用错误恢复功能(参见第 4.1.3.2 节),主机软件可以选择控制器在读取已释放或未写入的块时的行为。如果已使用错误恢复功能中的 DULBE 位启用该错误,则控制器应中止包含已释放或未写入的块(状态为“已释放或未写入的逻辑块”)的复制、读取、验证或比较命令。

对于支持此功能的某些 NVME 磁盘型号,您似乎可以利用它来检索一个块是否被修剪/未写入。

但我不知道有哪个模型支持这个功能,至少或不Samsung SSD 980 PRO 1TB支持INTEL P4510 1TB

# nvme id-ns /dev/nvme0n1 -H | grep "Deallocated or Unwritten Logical Block error"
  [2:2] : 0     Deallocated or Unwritten Logical Block error Not Supported

相关内容