This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch remove-partial-file in repository https://gitbox.apache.org/repos/asf/opendal.git
commit b8e66027a32921bb3e5e7580772df41799303c61 Author: Xuanwo <[email protected]> AuthorDate: Wed Jun 25 15:16:31 2025 +0800 fix(services/fs): Avoid creating partial files Signed-off-by: Xuanwo <[email protected]> --- core/src/services/fs/writer.rs | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/core/src/services/fs/writer.rs b/core/src/services/fs/writer.rs index 97d75f785..ff4e3ba34 100644 --- a/core/src/services/fs/writer.rs +++ b/core/src/services/fs/writer.rs @@ -40,25 +40,37 @@ impl FsWriter { pub async fn create(core: Arc<FsCore>, path: &str, op: OpWrite) -> Result<Self> { let target_path = core.ensure_write_abs_path(&core.root, path).await?; - // Create a target file using our OpWrite to check for permissions and existence. - // - // If target check passed, we can go decide which path we should go for writing. - let target_file = core.fs_write(&target_path, &op).await?; + // Quick path while atomic_write_dir is not set. + if core.atomic_write_dir.is_none() { + let target_file = core.fs_write(&target_path, &op).await?; + + return Ok(Self { + target_path, + temp_path: None, + f: target_file, + }); + } - // file is created success with append. let is_append = op.append(); - // file is created success with if_not_exists. - let is_exist = !op.if_not_exists(); - - let (mut f, mut temp_path) = (target_file, None); - if core.atomic_write_dir.is_some() { - // The only case we allow write in place is the file - // exists and users request for append writing. - if !(is_append && is_exist) { - (f, temp_path) = core.fs_tempfile_write(path).await?; - } + let is_exist = tokio::fs::try_exists(&target_path) + .await + .map_err(new_std_io_error)?; + if op.if_not_exists() && is_exist { + return Err(Error::new( + ErrorKind::ConditionNotMatch, + "file already exists, doesn't match the condition if_not_exists", + )); } + // The only case we allow write in place is the file + // exists and users request for append writing. + let (f, temp_path) = if !(is_append && is_exist) { + core.fs_tempfile_write(path).await? + } else { + let f = core.fs_write(&target_path, &op).await?; + (f, None) + }; + Ok(Self { target_path, temp_path,
