contenthash: fix hardlinks checksum on handlechange

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-19.03
Tonis Tiigi 2019-03-15 15:33:03 -07:00
parent c0c9306964
commit 23e1cd35d9
1 changed files with 32 additions and 0 deletions

View File

@ -91,6 +91,7 @@ func (cm *cacheManager) GetCacheContext(ctx context.Context, md *metadata.Storag
cm.lruMu.Unlock()
if ok {
cm.locker.Unlock(md.ID())
v.(*cacheContext).linkMap = map[string][][]byte{}
return v.(*cacheContext), nil
}
cc, err := newCacheContext(md)
@ -115,6 +116,7 @@ func (cm *cacheManager) SetCacheContext(ctx context.Context, md *metadata.Storag
md: md,
tree: cci.(*cacheContext).tree,
dirtyMap: map[string]struct{}{},
linkMap: map[string][][]byte{},
}
} else {
if err := cc.save(); err != nil {
@ -137,6 +139,7 @@ type cacheContext struct {
txn *iradix.Txn
node *iradix.Node
dirtyMap map[string]struct{}
linkMap map[string][][]byte
}
type mount struct {
@ -181,6 +184,7 @@ func newCacheContext(md *metadata.StorageItem) (*cacheContext, error) {
md: md,
tree: iradix.New(),
dirtyMap: map[string]struct{}{},
linkMap: map[string][][]byte{},
}
if err := cc.load(); err != nil {
return nil, err
@ -313,7 +317,35 @@ func (cc *cacheContext) HandleChange(kind fsutil.ChangeKind, p string, fi os.Fil
p += "/"
}
cr.Digest = h.Digest()
// if we receive a hardlink just use the digest of the source
// note that the source may be called later because data writing is async
if fi.Mode()&os.ModeSymlink == 0 && stat.Linkname != "" {
ln := path.Join("/", filepath.ToSlash(stat.Linkname))
v, ok := cc.txn.Get(convertPathToKey([]byte(ln)))
if ok {
cp := *v.(*CacheRecord)
cr = &cp
}
cc.linkMap[ln] = append(cc.linkMap[ln], k)
}
cc.txn.Insert(k, cr)
if !fi.IsDir() {
if links, ok := cc.linkMap[p]; ok {
for _, l := range links {
pp := convertKeyToPath(l)
cc.txn.Insert(l, cr)
d := path.Dir(string(pp))
if d == "/" {
d = ""
}
cc.dirtyMap[d] = struct{}{}
}
delete(cc.linkMap, p)
}
}
d := path.Dir(p)
if d == "/" {
d = ""