diff --git a/libs/utils/src/fs_ext.rs b/libs/utils/src/fs_ext.rs index 4bd08674f1..77e2dcf102 100644 --- a/libs/utils/src/fs_ext.rs +++ b/libs/utils/src/fs_ext.rs @@ -43,32 +43,31 @@ pub async fn list_dir(path: impl AsRef) -> anyhow::Result> { /// /// The idempotency implies that we return `Ok(())`` even if the file is already gone or has never existed, /// unlike `remove_dir_all` from std/tokio. -pub async fn remove_dir_all io::Error>( - path: impl AsRef, - cancel: crate::backoff::Cancel, -) -> io::Result<()> { - crate::backoff::retry( - || async { - match tokio::fs::remove_dir_all(path.as_ref()).await { - // If the directory is gone, we are done. - Err(e) if e.kind() == io::ErrorKind::NotFound && !path.as_ref().exists() => Ok(()), - other => other, - } - }, - |err| { - if err.kind() == io::ErrorKind::NotFound { - // We got a not found error and the directory still exists. - // This was likely due to a removal we are racing with, so retry. - return false; - } - true - }, - 3, - u32::MAX, - "directory removal", - cancel, - ) - .await +pub fn remove_dir_all(path: impl AsRef) -> io::Result<()> { + fn strip_not_found(v: io::Result) -> Option> { + match v { + Err(e) if e.kind() == io::ErrorKind::NotFound => None, + other => Some(other), + } + } + let Some(list) = strip_not_found(std::fs::read_dir(path)) else { + return Ok(()); + }; + for entry in list? { + let Some(entry) = strip_not_found(entry) else { + continue; + }; + let entry = entry?; + let Some(file_type) = strip_not_found(entry.file_type()) else { + continue; + }; + if file_type?.is_dir() { + remove_dir_all(entry.path())?; + } else { + strip_not_found(std::fs::remove_file(entry.path())).unwrap_or(Ok(()))?; + } + } + Ok(()) } pub fn ignore_not_found(e: io::Error) -> io::Result<()> { diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 4da42e509d..d7ee413481 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -3198,7 +3198,7 @@ impl Tenant { )); scopeguard::defer! { - if let Err(e) = utils::fs_ext::remove_dir_all(&temp_path, backoff::Cancel::new(CancellationToken::new(), || panic!())).await { + if let Err(e) = utils::fs_ext::remove_dir_all(&temp_path) { error!("Failed to remove temporary initdb archive '{temp_path}': {e}"); } }