github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/layer/mounted_layer.go (about)

     1  package layer // import "github.com/docker/docker/layer"
     2  
     3  import (
     4  	"io"
     5  	"sync"
     6  
     7  	"github.com/docker/docker/pkg/archive"
     8  	"github.com/docker/docker/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  }