github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/layer/mounted_layer.go (about) 1 package layer // import "github.com/demonoid81/moby/layer" 2 3 import ( 4 "io" 5 "sync" 6 7 "github.com/demonoid81/moby/pkg/archive" 8 "github.com/demonoid81/moby/pkg/containerfs" 9 ) 10 11 type mountedLayer struct { 12 name string 13 mountID string 14 initID string 15 parent *roLayer 16 layerStore *layerStore 17 18 sync.Mutex 19 references map[RWLayer]*referencedRWLayer 20 } 21 22 func (ml *mountedLayer) cacheParent() string { 23 if ml.initID != "" { 24 return ml.initID 25 } 26 if ml.parent != nil { 27 return ml.parent.cacheID 28 } 29 return "" 30 } 31 32 func (ml *mountedLayer) TarStream() (io.ReadCloser, error) { 33 return ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent()) 34 } 35 36 func (ml *mountedLayer) Name() string { 37 return ml.name 38 } 39 40 func (ml *mountedLayer) Parent() Layer { 41 if ml.parent != nil { 42 return ml.parent 43 } 44 45 // Return a nil interface instead of an interface wrapping a nil 46 // pointer. 47 return nil 48 } 49 50 func (ml *mountedLayer) Size() (int64, error) { 51 return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent()) 52 } 53 54 func (ml *mountedLayer) Changes() ([]archive.Change, error) { 55 return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent()) 56 } 57 58 func (ml *mountedLayer) Metadata() (map[string]string, error) { 59 return ml.layerStore.driver.GetMetadata(ml.mountID) 60 } 61 62 func (ml *mountedLayer) getReference() RWLayer { 63 ref := &referencedRWLayer{ 64 mountedLayer: ml, 65 } 66 ml.Lock() 67 ml.references[ref] = ref 68 ml.Unlock() 69 70 return ref 71 } 72 73 func (ml *mountedLayer) hasReferences() bool { 74 ml.Lock() 75 ret := len(ml.references) > 0 76 ml.Unlock() 77 78 return ret 79 } 80 81 func (ml *mountedLayer) deleteReference(ref RWLayer) error { 82 ml.Lock() 83 defer ml.Unlock() 84 if _, ok := ml.references[ref]; !ok { 85 return ErrLayerNotRetained 86 } 87 delete(ml.references, ref) 88 return nil 89 } 90 91 func (ml *mountedLayer) retakeReference(r RWLayer) { 92 if ref, ok := r.(*referencedRWLayer); ok { 93 ml.Lock() 94 ml.references[ref] = ref 95 ml.Unlock() 96 } 97 } 98 99 type referencedRWLayer struct { 100 *mountedLayer 101 } 102 103 func (rl *referencedRWLayer) Mount(mountLabel string) (containerfs.ContainerFS, error) { 104 return rl.layerStore.driver.Get(rl.mountedLayer.mountID, mountLabel) 105 } 106 107 // Unmount decrements the activity count and unmounts the underlying layer 108 // Callers should only call `Unmount` once per call to `Mount`, even on error. 109 func (rl *referencedRWLayer) Unmount() error { 110 return rl.layerStore.driver.Put(rl.mountedLayer.mountID) 111 } 112 113 // ApplyDiff applies specified diff to the layer 114 func (rl *referencedRWLayer) ApplyDiff(diff io.Reader) (int64, error) { 115 return rl.layerStore.driver.ApplyDiff(rl.mountID, rl.cacheParent(), diff) 116 }