github.com/Cloud-Foundations/Dominator@v0.3.4/lib/objectserver/filesystem/stash.go (about) 1 package filesystem 2 3 import ( 4 "errors" 5 "io" 6 "os" 7 "path" 8 9 "github.com/Cloud-Foundations/Dominator/lib/fsutil" 10 "github.com/Cloud-Foundations/Dominator/lib/hash" 11 "github.com/Cloud-Foundations/Dominator/lib/objectcache" 12 ) 13 14 var stashDirectory string = ".stash" 15 16 func (objSrv *ObjectServer) commitObject(hashVal hash.Hash) error { 17 hashName := objectcache.HashToFilename(hashVal) 18 filename := path.Join(objSrv.BaseDirectory, hashName) 19 stashFilename := path.Join(objSrv.BaseDirectory, stashDirectory, hashName) 20 fi, err := os.Lstat(stashFilename) 21 if err != nil { 22 if length, _ := objSrv.checkObject(hashVal); length > 0 { 23 return nil // Previously committed: return success. 24 } 25 return err 26 } 27 if !fi.Mode().IsRegular() { 28 fsutil.ForceRemove(stashFilename) 29 return errors.New("existing non-file: " + stashFilename) 30 } 31 err = os.MkdirAll(path.Dir(filename), fsutil.PrivateDirPerms) 32 if err != nil { 33 return err 34 } 35 objSrv.rwLock.Lock() 36 defer objSrv.rwLock.Unlock() 37 if _, ok := objSrv.objects[hashVal]; ok { 38 fsutil.ForceRemove(stashFilename) 39 // Run in a goroutine to keep outside of the lock. 40 go objSrv.addCallback(hashVal, uint64(fi.Size()), false) 41 return nil 42 } else { 43 objSrv.add(&objectType{hash: hashVal, size: uint64(fi.Size())}) 44 if objSrv.addCallback != nil { 45 // Run in a goroutine to keep outside of the lock. 46 go objSrv.addCallback(hashVal, uint64(fi.Size()), true) 47 } 48 return os.Rename(stashFilename, filename) 49 } 50 } 51 52 func (objSrv *ObjectServer) deleteStashedObject(hashVal hash.Hash) error { 53 filename := path.Join(objSrv.BaseDirectory, stashDirectory, 54 objectcache.HashToFilename(hashVal)) 55 return os.Remove(filename) 56 } 57 58 func (objSrv *ObjectServer) stashOrVerifyObject(reader io.Reader, 59 length uint64, expectedHash *hash.Hash) (hash.Hash, []byte, error) { 60 hashVal, data, err := objectcache.ReadObject(reader, length, expectedHash) 61 if err != nil { 62 return hashVal, nil, err 63 } 64 hashName := objectcache.HashToFilename(hashVal) 65 filename := path.Join(objSrv.BaseDirectory, hashName) 66 // Check for existing object and collision. 67 if length, err := objSrv.checkObject(hashVal); err != nil { 68 return hashVal, nil, err 69 } else if length > 0 { 70 if err := collisionCheck(data, filename, int64(length)); err != nil { 71 return hashVal, nil, err 72 } 73 return hashVal, nil, nil 74 } 75 // Check for existing stashed object and collision. 76 stashFilename := path.Join(objSrv.BaseDirectory, stashDirectory, hashName) 77 if _, err := objSrv.addOrCompare(hashVal, data, stashFilename); err != nil { 78 return hashVal, nil, err 79 } else { 80 return hashVal, data, nil 81 } 82 }