From 5e1daf999b11f8c3bc314aebf74c4469aec602cf Mon Sep 17 00:00:00 2001 From: BLumia Date: Thu, 3 Sep 2026 10:59:08 +0800 Subject: [PATCH] fix: fsync autostart file to survive hard reboot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Root cause: saveAutostartEntry only called QFile::flush() after writing the autostart desktop file, which flushes Qt's internal buffer to the OS fd but leaves data in the page cache. A hard reboot before the OS flushes the page cache loses the file content, causing the autostart entry to be empty or missing. 2. Fix: call ::fsync() on the file descriptor after flush() to force data to physical disk, and fsync the parent directory to persist the directory entry for newly created files. 3. Impact: no signature or return-value change; fsync failure only logs a warning without altering existing behavior. All callers remain compatible. Log: ensure autostart desktop files persist across hard reboots Influence: 1. Test setting autostart then hard reboot, verify autostart works 2. Test cancel-disk-encryption interrupted by hard reboot, verify the resume dialog appears after reboot 3. Verify normal autostart enable/disable has no regression fix: 修复自启动文件硬重启后未落盘的问题 1. 根因:saveAutostartEntry 写入 autostart desktop 文件后仅调用 QFile::flush(),该操作只将 Qt 内部缓冲刷到 OS fd,数据仍停留 在 page cache 中。硬重启时 page cache 丢失,导致文件内容为空 或不完整,自启动条目失效。 2. 方案:在 flush() 成功后对文件描述符调用 ::fsync() 强制数据 写入物理磁盘,并对父目录做 fsync 确保新文件目录项持久化。 3. 影响:不改变函数签名和返回值语义;fsync 失败仅记录警告不 改变现有行为,所有调用者保持兼容。 Log: 确保自启动 desktop 文件在硬重启后不丢失 Influence: 1. 测试设置自启动后硬重启,验证自启动正常生效 2. 测试取消分区加密过程中硬重启,验证重启后继续取消加密 对话框正常弹出 3. 验证正常的自启动启用/禁用功能无回归 PMS: BUG-375555 --- src/dbus/applicationservice.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/dbus/applicationservice.cpp b/src/dbus/applicationservice.cpp index e72b0588..95d42498 100644 --- a/src/dbus/applicationservice.cpp +++ b/src/dbus/applicationservice.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #include #include @@ -1037,6 +1039,23 @@ bool ApplicationService::saveAutostartEntry(const QString &fileName, const Deskt return false; } + // Ensure file content is flushed to physical disk so the autostart entry + // survives a hard reboot (BUG-375555). + if (autostartFile.handle() != -1) { + if (::fsync(autostartFile.handle()) != 0) { + qWarning() << "fsync autostart file failed:" << fileName; + } + } + + // Sync the parent directory so the directory entry of a newly created file + // is also persisted to disk. + const QByteArray parentDirPath = autostartFileInfo.absolutePath().toLocal8Bit(); + int dirFd = ::open(parentDirPath.constData(), O_RDONLY | O_DIRECTORY); + if (dirFd != -1) { + ::fsync(dirFd); + ::close(dirFd); + } + return true; }