linux loopback remount-ro,ext4_da_writepages:jbd2_start:8192 页,ino 130135;错误 -30

linux loopback remount-ro,ext4_da_writepages:jbd2_start:8192 页,ino 130135;错误 -30

我有一个用 ext4 格式化的环回设备(^has_journal,禁用日志记录)。

在关机期间,当我尝试强制以只读方式重新挂载时,回送挂载文件系统。echo“u”> /proc/sysrq-trigger

重新安装 ext4_da_writepages 后,我看到这些 ext4 错误:jbd2_start:8192 页,ino 130135;错误 -30

(错误 30 是 -EROFS,由于写回到只读文件系统而导致的错误)。作为重新挂载的一部分,我看到 Linux 调用 invalidate_bdev(),我猜这不应该允许任何写回发生。不确定为什么我会看到这些错误。

当我将环回设备格式化为 vfat 时,我没有看到任何错误。

任何帮助都将受到赞赏。

谢谢

答案1

这是因为 sysrq-trigger 仅适用于紧急情况,并且不具备任何智能。

查看内核源代码中的 fs/super.c:do_emergency_remount(),似乎它会按照列表中的顺序重新挂载只读文件系统(例如,这与执行“cat /proc/mounts”时看到的顺序相同)。这很不幸,因为它很可能会首先以只读方式重新挂载父文件系统,然后尝试卸载回送文件系统,这将触发写入(超级块和任何剩余的修改数据/元数据)到父文件系统,而父文件系统已经是只读的,因此会失败并出现 -EROFS。

解决方案是使用常规工具来卸载并重新挂载 R/O 而不是 sysrq-trigger,例如使用:

umount -a

(这将卸载所有可以卸载的内容,然后重新挂载 rootfs R/O)

或者按正确的顺序手动运行:

mount -oremount,ro /dev/xxx

如果您需要使用 /proc/sysrq-trigger(为什么?),那么您可以尝试让内核看到您想要的顺序(如果可能的话,我还没有深入研究过)或修改内核以执行从后到前的排序(而不是从前到后)。它可能并不完美(对于一些更复杂的设置,它也可能不正确),但在大多数情况下(如果不是全部)它都比当前解决方案更好。我敢说如果您尝试推动它,它甚至可能会进入主线内核,因为在特定位置遍历该特定列表对性能并不重要,因此从后向遍历列表导致的缓存未命中等不是问题。

顺便说一句,您看不到 VFAT 的错误(如果它最近没有被修改),因为 VFAT(由于其简单性)不需要在 umount 时将修改后的超级块写入磁盘。

相关内容