修复策划V2不可变文件失败残留
失败时清理已创建的空文件或截断文件 保留已有文件的幂等与内容冲突校验
This commit is contained in:
+18
-7
@@ -839,13 +839,24 @@ fn create_v2_immutable_file(root: &Path, relative: &str, bytes: &[u8]) -> Result
|
||||
.open(&path)
|
||||
{
|
||||
Ok(mut file) => {
|
||||
harden_new_game_creator_private_path(&path, false, "Planning V2 文件")?;
|
||||
file.write_all(bytes)
|
||||
.and_then(|_| file.sync_data())
|
||||
.map_err(|error| {
|
||||
format!("写入 Planning V2 文件失败:{}: {error}", path.display())
|
||||
})?;
|
||||
Ok(())
|
||||
// `create_new` has already made the final path visible. Every
|
||||
// subsequent step must therefore be transactional from the
|
||||
// caller's perspective: a failed ACL repair, partial write, or
|
||||
// failed sync must not leave an empty/truncated immutable file
|
||||
// that would permanently block a retry.
|
||||
let result = (|| {
|
||||
harden_new_game_creator_private_path(&path, false, "Planning V2 文件")?;
|
||||
file.write_all(bytes)
|
||||
.and_then(|_| file.sync_data())
|
||||
.map_err(|error| {
|
||||
format!("写入 Planning V2 文件失败:{}: {error}", path.display())
|
||||
})?;
|
||||
Ok(())
|
||||
})();
|
||||
if result.is_err() {
|
||||
let _ = fs::remove_file(&path);
|
||||
}
|
||||
result
|
||||
}
|
||||
Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => {
|
||||
prepare_game_creator_private_path_for_read(&path, false, "Planning V2 文件")?;
|
||||
|
||||
Reference in New Issue
Block a user