Skip to content

Commit ed6f34b

Browse files
authored
Add debug logging to FUSE flush to make upload completion clearer (#1247)
In some edge cases, Mountpoint will not be able to complete the MPU before the file is closed. For instance, we will not complete uploads where no bytes have been written since it can be common for applications to fork and result in file descriptor being closed before writing begins. If an application relies on close completing before another system queries S3, it could lead to a race condition where the object is not yet in S3. While this is an edge case, this change adds debug logging which can help identify when this behavior occurs. ### Does this change impact existing behavior? Logging change only. ### Does this change need a changelog entry? Does it require a version change? No, logging change only. --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and I agree to the terms of the [Developer Certificate of Origin (DCO)](https://developercertificate.org/). --------- Signed-off-by: Daniel Carl Jones <[email protected]>
1 parent 981a3e1 commit ed6f34b

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

mountpoint-s3/src/fs.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -850,11 +850,22 @@ where
850850
FileHandleState::Write(write_state) => write_state,
851851
};
852852

853-
let result = write_state.complete_if_in_progress(&file_handle.full_key).await;
853+
let complete_result = write_state.complete_if_in_progress(&file_handle.full_key).await;
854854
metrics::gauge!("fs.current_handles", "type" => "write").decrement(1.0);
855-
// Errors won't actually be seen by the user because `release` is async,
856-
// but it's the right thing to do.
857-
result
855+
856+
match complete_result {
857+
Ok(upload_completed_async) => {
858+
if upload_completed_async {
859+
debug!(key = ?&file_handle.full_key, "upload completed async after file was closed");
860+
}
861+
Ok(())
862+
}
863+
Err(e) => {
864+
// Errors won't actually be seen by the user because `release` is async,
865+
// but it's the right thing to do so we'll return it.
866+
Err(e)
867+
}
868+
}
858869
}
859870

860871
pub async fn rmdir(&self, parent_ino: InodeNo, name: &OsStr) -> Result<(), Error> {

mountpoint-s3/src/fs/handles.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::str::FromStr as _;
22

33
use mountpoint_s3_client::types::ETag;
44
use mountpoint_s3_client::ObjectClient;
5-
use tracing::{debug, error, trace};
5+
use tracing::{debug, error};
66

77
use crate::object::ObjectId;
88
use crate::prefetch::Prefetch;
@@ -295,15 +295,13 @@ where
295295
}
296296
UploadState::MPUInProgress { request, .. } => {
297297
if request.size() == 0 {
298-
trace!(key, "not completing upload because nothing was written");
298+
debug!(key, "not completing upload because nothing was written yet");
299299
return Ok(());
300300
}
301301
if !are_from_same_process(open_pid, pid) {
302-
trace!(
302+
debug!(
303303
key,
304-
pid,
305-
open_pid,
306-
"not completing upload because current pid differs from pid at open"
304+
pid, open_pid, "not completing upload because current PID differs from PID at open",
307305
);
308306
return Ok(());
309307
}
@@ -329,16 +327,25 @@ where
329327
result
330328
}
331329

332-
pub async fn complete_if_in_progress(self, key: &str) -> Result<(), Error> {
330+
/// Check state of upload, and complete the upload if it is still in-progress.
331+
///
332+
/// When successful, returns `true` where the upload was still in-progress and thus completed by this method call.
333+
pub async fn complete_if_in_progress(self, key: &str) -> Result<bool, Error> {
333334
match self {
334335
UploadState::AppendInProgress {
335336
request,
336337
handle,
337338
initial_etag,
338339
..
339-
} => Self::complete_append(request, key, handle, initial_etag).await,
340-
UploadState::MPUInProgress { request, handle, .. } => Self::complete_upload(request, key, handle).await,
341-
UploadState::Failed(_) | UploadState::Completed => Ok(()),
340+
} => {
341+
Self::complete_append(request, key, handle, initial_etag).await?;
342+
Ok(true)
343+
}
344+
UploadState::MPUInProgress { request, handle, .. } => {
345+
Self::complete_upload(request, key, handle).await?;
346+
Ok(true)
347+
}
348+
UploadState::Failed(_) | UploadState::Completed => Ok(false),
342349
}
343350
}
344351

0 commit comments

Comments
 (0)