dmesg 中的“Synchronize Cache(10) failed: Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK”是什么意思?

dmesg 中的“Synchronize Cache(10) failed: Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK”是什么意思?

当我关闭外部 USB 3.0 SSD(硬盘外壳包含 2.5 英寸三星 SSD,通过 USB 3.0 电缆连接到 USB-A 2.0 或 3.0 计算机端口;分区已经卸载)时

$ sudo udisksctl power-off -b /dev/sdg

我收到了消息

[ 8618.812659] sd 8:0:0:0: [sdg] Synchronizing SCSI cache
[ 8619.120991] sd 8:0:0:0: [sdg] Synchronize Cache(10) failed: Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK
[ 8619.295465] usb 1-8: USB disconnect, device number 13

sudo dmesg输出中。根据之前的 dmesg 输出,读写缓存均已启用。对我来说,“失败”听起来一般不太好。在最好的情况下,它是伪程序架构或伪编程的表现(在不再需要或可能时尝试刷新读/写缓存,甚至发出误导性的 printf),在最坏的情况下,它会导致潜在的数据丢失或损坏(写入缓存包含要刷新的数据,但这些数据永远不会进入驱动器)。幕后发生了什么?这是我需要担心的事情吗?

使用 USB 笔式驱动器时不会出现上述消息https://www.amazon.de/dp/B07RT8KG8N代替上述 SSD;这与 USB 笔式驱动器未启用缓存一致。

答案1

https://github.com/torvalds/linux/blob/v5.18/drivers/scsi/sd.c#L3530

sd_shutdown()依次调用sd_sync_cache()

我的猜测是,某些现有的结构使得sd_shutdown()在从调用时表现不同变得不方便sd_remove(),而且由于它不会造成任何实际问题,所以没有人足够关心使其“更好”(更不用说如果不小心进行这种“毫无意义的”改进可能会导致回归)。

但我可能是错的(比如,无论如何,都有充分的理由打电话sd_sync_cache())。无论如何,这种问题属于 linux-scsi 邮件列表。更不用说它是否超出了本网站的范围,那里的开发人员可以为您提供更好的答案。在这里,您往往会得到不相关的答案。(或者更糟的是,“您的磁盘可能快坏了”/“检查 SMART” FUD。)

顺便说一句,我认为这里真正令人担忧的是,卸载 / sync(而不是sg_syncfrom sg3_utils)是否能保证设备上的写回缓存被刷新(而不仅仅是内存中的脏页)?我不认为 Linux 可以承受这样的缺陷,但sg_sync有时我确实会在卸载后运行(因为我是个偏执狂)。(编辑:参见https://github.com/torvalds/linux/blob/v5.18/drivers/scsi/sd.c#L1249

如果还不够明显,那么您是否看到该消息并不取决于缓存是否为空。据我所知,SCSI 或 ATA 中甚至没有办法检查这一点。udisksctl这里也无关紧要,即使您断开驱动器连接,您也会看到该消息。


事实上,sd_shutdown()被叫去sd_removed()(并且sd_sync_cache()被叫去sd_shutdown())可以追溯到上游内核的最早 git 提交。那时sd_shutdown()所做的只不过是sd_sync_cache()。根据对的评论sd_remove(),似乎至少有一个调用的原因sd_sync_cache()sd_remove()不仅sd_remove()在磁盘分离时(之后)调用,而且在卸载 scsi 磁盘模块时也调用,在这种情况下SYNCHRONIZE_CACHE不会失败。但从我的角度来看,SYNCHRONIZE_CACHE在卸载 sd mod 时是否真的有必要仍然存在疑问,因为我不确定当挂载涉及 SCSI 磁盘上的文件系统时是否可能这样做。

但是,就我所知,如果我们想要SYNCHRONIZE_CACHE在的情况下“抑制”发送sd_remove(),我们需要在其中设置sdkp->WCE0,从语义上讲,这可能有点肮脏。

也很难说当前sd_shutdown()所做的其他事情在这两种情况下是否都是必要的sd_remove()。(我的意思是,它被调用的原因可能完全是历史性的。)但再次重申,当一切都很好且无害时,我怀疑任何开发人员都会冒着回归的风险。

答案2

udisksctl=issue 命令的手册页man udisksctl显示:

power-off
           Arranges for the drive to be safely removed and powered off. On the OS side this includes ensuring that no process is
           using the drive, then requesting that in-flight buffers and caches are committed to stable storage. The exact steps
           for powering off the drive depends on the drive itself and the interconnect used. For drives connected through USB,
           the effect is that the USB device will be deconfigured followed by disabling the upstream hub port it is connected
           to.

           Note that as some physical devices contain multiple drives (for example 4-in-1 flash card reader USB devices)
           powering off one drive may affect other drives. As such there are not a lot of guarantees associated with performing
           this action. Usually the effect is that the drive disappears as if it was unplugged.

因此看来 udisksctl 应该可以安全地移除驱动器:

  1. 从缓存中写入数据
  2. 卸载驱动器
  3. 把它关掉

错误并不能说明什么,但如果您想确保一切正常,您应该在之前发出一个命令:sync并等待该命令将所有内容写入驱动器。如果sync下一个命令提示符没有错误消息,您可以发出命令,然后移除驱动器。

如果缓存未写入驱动器,则可能会丢失数据。然后文件末尾或文件表(NTFS 的 MFT 或 ext4 的 inode 表)无法按应有的方式更新。

如果您怀疑数据丢失,您可以通过将最近写入该驱动器的文件与原始副本(源,甚至是复制过程之后)进行比较来验证。

编辑:

从错误消息来看,您的磁盘似乎快坏了。请进行完整备份并检查该驱动器的 SMART 信息。

相关内容