Retry deleting a directory
It's possible that a file in the directory is pending deletion. In that case we might succeed after a few attempts.
This commit is contained in:
parent
8b1f85caed
commit
8dc4696b3b
@ -1018,6 +1018,10 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> {
|
fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> {
|
||||||
|
// When deleting files we may loop this many times when certain error conditions occur.
|
||||||
|
// This allows remove_dir_all to succeed when the error is temporary.
|
||||||
|
const MAX_RETRIES: u32 = 10;
|
||||||
|
|
||||||
let mut buffer = DirBuff::new();
|
let mut buffer = DirBuff::new();
|
||||||
let mut dirlist = vec![f.duplicate()?];
|
let mut dirlist = vec![f.duplicate()?];
|
||||||
|
|
||||||
@ -1040,7 +1044,6 @@ fn copy_handle(f: &File) -> mem::ManuallyDrop<File> {
|
|||||||
)?;
|
)?;
|
||||||
dirlist.push(child_dir);
|
dirlist.push(child_dir);
|
||||||
} else {
|
} else {
|
||||||
const MAX_RETRIES: u32 = 10;
|
|
||||||
for i in 1..=MAX_RETRIES {
|
for i in 1..=MAX_RETRIES {
|
||||||
let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
|
let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
|
||||||
match result {
|
match result {
|
||||||
@ -1062,7 +1065,17 @@ fn copy_handle(f: &File) -> mem::ManuallyDrop<File> {
|
|||||||
// If there were no more files then delete the directory.
|
// If there were no more files then delete the directory.
|
||||||
if !more_data {
|
if !more_data {
|
||||||
if let Some(dir) = dirlist.pop() {
|
if let Some(dir) = dirlist.pop() {
|
||||||
delete(&dir)?;
|
// Retry deleting a few times in case we need to wait for a file to be deleted.
|
||||||
|
for i in 1..=MAX_RETRIES {
|
||||||
|
let result = delete(&dir);
|
||||||
|
if let Err(e) = result {
|
||||||
|
if i == MAX_RETRIES || e.kind() != io::ErrorKind::DirectoryNotEmpty {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user