@@ -1456,6 +1456,30 @@ func (s *store) putLayer(rlstore rwLayerStore, id string, parentLayer *Layer, na
14561456 return rlstore .create (id , parentLayer , names , mountLabel , nil , options , writeable , slo )
14571457}
14581458
1459+ // On entry:
1460+ // - rlstore must be locked for writing
1461+ // - rlstores MUST NOT be locked
1462+ func getParentLayer (rlstore rwLayerStore , rlstores []roLayerStore , parent string ) (* Layer , error ) {
1463+ var ilayer * Layer
1464+ for _ , l := range append ([]roLayerStore {rlstore }, rlstores ... ) {
1465+ lstore := l
1466+ if lstore != rlstore {
1467+ if err := lstore .startReading (); err != nil {
1468+ return nil , err
1469+ }
1470+ defer lstore .stopReading ()
1471+ }
1472+ if l , err := lstore .Get (parent ); err == nil && l != nil {
1473+ ilayer = l
1474+ break
1475+ }
1476+ }
1477+ if ilayer == nil {
1478+ return nil , ErrLayerUnknown
1479+ }
1480+ return ilayer , nil
1481+ }
1482+
14591483// On entry:
14601484// - rlstore must be locked for writing
14611485// - rlstores MUST NOT be locked
@@ -1478,25 +1502,11 @@ func populateLayerOptions(s *store, rlstore rwLayerStore, rlstores []roLayerStor
14781502 uidMap := options .UIDMap
14791503 gidMap := options .GIDMap
14801504 if parent != "" {
1481- var ilayer * Layer
1482- for _ , l := range append ([]roLayerStore {rlstore }, rlstores ... ) {
1483- lstore := l
1484- if lstore != rlstore {
1485- if err := lstore .startReading (); err != nil {
1486- return nil , nil , err
1487- }
1488- defer lstore .stopReading ()
1489- }
1490- if l , err := lstore .Get (parent ); err == nil && l != nil {
1491- ilayer = l
1492- parent = ilayer .ID
1493- break
1494- }
1495- }
1496- if ilayer == nil {
1497- return nil , nil , ErrLayerUnknown
1505+ var err error
1506+ parentLayer , err = getParentLayer (rlstore , rlstores , parent )
1507+ if err != nil {
1508+ return nil , nil , err
14981509 }
1499- parentLayer = ilayer
15001510
15011511 if err := s .containerStore .startWriting (); err != nil {
15021512 return nil , nil , err
@@ -1512,10 +1522,10 @@ func populateLayerOptions(s *store, rlstore rwLayerStore, rlstores []roLayerStor
15121522 }
15131523 }
15141524 if ! options .HostUIDMapping && len (options .UIDMap ) == 0 {
1515- uidMap = ilayer .UIDMap
1525+ uidMap = parentLayer .UIDMap
15161526 }
15171527 if ! options .HostGIDMapping && len (options .GIDMap ) == 0 {
1518- gidMap = ilayer .GIDMap
1528+ gidMap = parentLayer .GIDMap
15191529 }
15201530 } else {
15211531 if ! options .HostUIDMapping && len (options .UIDMap ) == 0 {
@@ -1544,7 +1554,11 @@ func (s *store) PutLayer(id, parent string, names []string, mountLabel string, w
15441554 return nil , - 1 , err
15451555 }
15461556
1547- var slo * stagedLayerOptions
1557+ var (
1558+ slo * stagedLayerOptions
1559+ options * LayerOptions
1560+ parentLayer * Layer
1561+ )
15481562
15491563 if diff != nil {
15501564 m := rlstore .newMaybeStagedLayerExtraction (diff )
@@ -1553,10 +1567,32 @@ func (s *store) PutLayer(id, parent string, names []string, mountLabel string, w
15531567 logrus .Errorf ("Error cleaning up temporary directories: %v" , err )
15541568 }
15551569 }()
1556- err = rlstore .stageWithUnlockedStore (m , lOptions )
1557- if err != nil {
1558- return nil , - 1 , err
1570+ // driver can do unlocked staging so do that without holding the layer lock
1571+ if m .staging != nil {
1572+ // func so we have a scope for defer, we don't want to hold the lock for stageWithUnlockedStore()
1573+ layer , err := func () (* Layer , error ) {
1574+ if err := rlstore .startWriting (); err != nil {
1575+ return nil , err
1576+ }
1577+ defer rlstore .stopWriting ()
1578+
1579+ if layer , err := rlstore .checkIdOrNameConfict (id , names ); err != nil {
1580+ return layer , err
1581+ }
1582+
1583+ options , parentLayer , err = populateLayerOptions (s , rlstore , rlstores , parent , lOptions )
1584+ return nil , err
1585+ }()
1586+ if err != nil {
1587+ return layer , - 1 , err
1588+ }
1589+
1590+ err = rlstore .stageWithUnlockedStore (m , options )
1591+ if err != nil {
1592+ return nil , - 1 , err
1593+ }
15591594 }
1595+
15601596 slo = & stagedLayerOptions {
15611597 stagedLayerExtraction : m ,
15621598 }
@@ -1567,9 +1603,21 @@ func (s *store) PutLayer(id, parent string, names []string, mountLabel string, w
15671603 }
15681604 defer rlstore .stopWriting ()
15691605
1570- options , parentLayer , err := populateLayerOptions (s , rlstore , rlstores , parent , lOptions )
1571- if err != nil {
1572- return nil , - 1 , err
1606+ if parentLayer == nil {
1607+ // options where not populated yet
1608+ options , parentLayer , err = populateLayerOptions (s , rlstore , rlstores , parent , lOptions )
1609+ if err != nil {
1610+ return nil , - 1 , err
1611+ }
1612+ } else {
1613+ // We used the staged extraction without holding the lock.
1614+ // Check again that the parent layer is still valid and exists.
1615+ _ , err := getParentLayer (rlstore , rlstores , parentLayer .ID )
1616+ if err != nil {
1617+ return nil , - 1 , err
1618+ }
1619+ // FIXME: I guess we should compare the old parentLayer uid/gid mappings with the newly looked up layer here?
1620+ // Could it happen that a layer with the same id was deleted on recreated with new mapping while we where unlocked?
15731621 }
15741622 return s .putLayer (rlstore , id , parentLayer , names , mountLabel , writeable , options , slo )
15751623}
0 commit comments