forked from TrueCloudLab/rclone
webdav: fix race when creating directories - fixes #3035
Before this change a race condition existed in mkdir - the directory was attempted to be created - the parent didn't exist so it failed - the parent was created - the directory was created again The last step failed as the directory was created in a different thread. This was fixed by checking the error messages of MKCOL for both directory creations, rather than only the first.
This commit is contained in:
parent
415eeca6cf
commit
4827496234
1 changed files with 10 additions and 7 deletions
|
@ -644,10 +644,18 @@ func (f *Fs) _mkdir(dirPath string) error {
|
||||||
Path: dirPath,
|
Path: dirPath,
|
||||||
NoResponse: true,
|
NoResponse: true,
|
||||||
}
|
}
|
||||||
return f.pacer.Call(func() (bool, error) {
|
err := f.pacer.Call(func() (bool, error) {
|
||||||
resp, err := f.srv.Call(&opts)
|
resp, err := f.srv.Call(&opts)
|
||||||
return shouldRetry(resp, err)
|
return shouldRetry(resp, err)
|
||||||
})
|
})
|
||||||
|
if apiErr, ok := err.(*api.Error); ok {
|
||||||
|
// already exists
|
||||||
|
// owncloud returns 423/StatusLocked if the create is already in progress
|
||||||
|
if apiErr.StatusCode == http.StatusMethodNotAllowed || apiErr.StatusCode == http.StatusNotAcceptable || apiErr.StatusCode == http.StatusLocked {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkdir makes the directory and parents using native paths
|
// mkdir makes the directory and parents using native paths
|
||||||
|
@ -655,12 +663,7 @@ func (f *Fs) mkdir(dirPath string) error {
|
||||||
// defer log.Trace(dirPath, "")("")
|
// defer log.Trace(dirPath, "")("")
|
||||||
err := f._mkdir(dirPath)
|
err := f._mkdir(dirPath)
|
||||||
if apiErr, ok := err.(*api.Error); ok {
|
if apiErr, ok := err.(*api.Error); ok {
|
||||||
// already exists
|
// parent does not exist so create it first then try again
|
||||||
// owncloud returns 423/StatusLocked if the create is already in progress
|
|
||||||
if apiErr.StatusCode == http.StatusMethodNotAllowed || apiErr.StatusCode == http.StatusNotAcceptable || apiErr.StatusCode == http.StatusLocked {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// parent does not exist
|
|
||||||
if apiErr.StatusCode == http.StatusConflict {
|
if apiErr.StatusCode == http.StatusConflict {
|
||||||
err = f.mkParentDir(dirPath)
|
err = f.mkParentDir(dirPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue