mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
Add reliable RemoveAll to handle racy situations (#6227)
This commit is contained in:
committed by
Nitish Tiwari
parent
13fbb96736
commit
2dede2fdc2
@@ -22,6 +22,53 @@ import (
|
||||
"path"
|
||||
)
|
||||
|
||||
// Wrapper functions to os.RemoveAll, which calls reliableRemoveAll
|
||||
// this is to ensure that if there is a racy parent directory
|
||||
// create in between we can simply retry the operation.
|
||||
func removeAll(dirPath string) (err error) {
|
||||
if dirPath == "" {
|
||||
return errInvalidArgument
|
||||
}
|
||||
|
||||
if err = checkPathLength(dirPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = reliableRemoveAll(dirPath); err != nil {
|
||||
switch {
|
||||
case isSysErrNotDir(err):
|
||||
// File path cannot be verified since one of
|
||||
// the parents is a file.
|
||||
return errFileAccessDenied
|
||||
case isSysErrPathNotFound(err):
|
||||
// This is a special case should be handled only for
|
||||
// windows, because windows API does not return "not a
|
||||
// directory" error message. Handle this specifically
|
||||
// here.
|
||||
return errFileAccessDenied
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Reliably retries os.RemoveAll if for some reason os.RemoveAll returns
|
||||
// syscall.ENOTEMPTY (children has files).
|
||||
func reliableRemoveAll(dirPath string) (err error) {
|
||||
i := 0
|
||||
for {
|
||||
// Removes all the directories and files.
|
||||
if err = os.RemoveAll(dirPath); err != nil {
|
||||
// Retry only for the first retryable error.
|
||||
if isSysErrNotEmpty(err) && i == 0 {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Wrapper functions to os.MkdirAll, which calls reliableMkdirAll
|
||||
// this is to ensure that if there is a racy parent directory
|
||||
// delete in between we can simply retry the operation.
|
||||
|
||||
Reference in New Issue
Block a user