-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathref.go
83 lines (66 loc) · 1.84 KB
/
ref.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package blobstore
import (
"os"
)
// Ref increments the reference count for the blob with the given digest.
func (ls *localStore) Ref(digest string) (d Descriptor, err error) {
ls.Lock()
defer ls.Unlock()
// Avoid the (type, nil) interface issue.
d, blobErr := ls.ref(digest)
if blobErr != nil {
return nil, blobErr
}
return
}
// Deref decrements the reference count for the blob with the given digest. If
// no references to the blob remain, the blob will be removed from the store
// and blobs to which it links will also be dereferenced.
func (ls *localStore) Deref(digest string) error {
ls.Lock()
defer ls.Unlock()
// Avoid the (type, nil) interface issue.
blobErr := ls.deref(digest)
if blobErr != nil {
return blobErr
}
return nil
}
// ref is the unexported version of Ref which does not acquire the store lock
// before incrementing a blob reference count.
func (ls *localStore) ref(digest string) (Descriptor, *storeError) {
info, err := ls.getBlobInfo(digest)
if err != nil {
return nil, err
}
info.RefCount++
if err = ls.putBlobInfo(info); err != nil {
return nil, err
}
return newDescriptor(info), nil
}
// deref is the unexported version of Deref which does not acquire the store
// lock before decrementing the blob reference count.
func (ls *localStore) deref(digest string) *storeError {
info, err := ls.getBlobInfo(digest)
if err != nil {
return err
}
if info.RefCount > 0 { // Be careful to not overflow.
info.RefCount--
}
if info.RefCount > 0 {
return ls.putBlobInfo(info)
}
// Dereference blobs to which this one links.
for _, linkTo := range info.LinksTo {
if err = ls.deref(linkTo); !(err == nil || err.IsBlobNotExists()) {
return err
}
}
blobDirname := ls.blobDirname(digest)
if e := os.RemoveAll(blobDirname); e != nil {
return newError(errCodeCannotRemoveBlob, e.Error())
}
return nil
}