summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Borg <jakob@nym.se>2015-10-01 09:42:57 +0200
committerJakob Borg <jakob@nym.se>2015-10-02 08:01:00 +0200
commitf8b835c6be16bfe5c6233ec9389f0650523563c4 (patch)
treea70a1d839cab52c8504d00f4c8a5eecff5bdc3f3
parent5fab25effd3b79106d74bfc91e5eac6d81ab64c0 (diff)
Create missing directories
-rw-r--r--lib/model/sharedpullerstate.go20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/model/sharedpullerstate.go b/lib/model/sharedpullerstate.go
index 4828dcf5b..1a0dcf360 100644
--- a/lib/model/sharedpullerstate.go
+++ b/lib/model/sharedpullerstate.go
@@ -86,8 +86,24 @@ func (s *sharedPullerState) tempFile() (io.WriterAt, error) {
// here.
dir := filepath.Dir(s.tempName)
if info, err := os.Stat(dir); err != nil {
- s.failLocked("dst stat dir", err)
- return nil, err
+ if os.IsNotExist(err) {
+ // XXX: This works around a bug elsewhere, a race condition when
+ // things are deleted while being synced. However that happens, we
+ // end up with a directory for "foo" with the delete bit, but a
+ // file "foo/bar" that we want to sync. We never create the
+ // directory, and hence fail to create the file and end up looping
+ // forever on it. This breaks that by creating the directory; on
+ // next scan it'll be found and the delete bit on it is removed.
+ // The user can then clean up as they like...
+ l.Infoln("Resurrecting directory", dir)
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ s.failLocked("resurrect dir", err)
+ return nil, err
+ }
+ } else {
+ s.failLocked("dst stat dir", err)
+ return nil, err
+ }
} else if info.Mode()&0200 == 0 {
err := os.Chmod(dir, 0755)
if !s.ignorePerms && err == nil {