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