aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/pkg/pkg.go44
1 files changed, 44 insertions, 0 deletions
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index dd48d847..59662b1e 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -665,6 +665,9 @@ type ScrubError struct {
// Dangling identifier symlinks. This can happen if the content-addressed
// entry was removed while scrubbing due to a checksum mismatch.
DanglingIdentifiers []ID
+ // Dangling status files. This can happen if a dangling status symlink was
+ // removed while scrubbing.
+ DanglingStatus []ID
// Miscellaneous errors, including [os.ReadDir] on checksum and identifier
// directories, [Decode] on entry names and [os.RemoveAll] on inconsistent
// entries.
@@ -716,6 +719,13 @@ func (e *ScrubError) Error() string {
}
segments = append(segments, s)
}
+ if len(e.DanglingStatus) > 0 {
+ s := "dangling status:\n"
+ for _, id := range e.DanglingStatus {
+ s += Encode(id) + "\n"
+ }
+ segments = append(segments, s)
+ }
if len(e.Errs) > 0 {
s := "errors during scrub:\n"
for pathname, errs := range e.errs {
@@ -894,6 +904,36 @@ func (c *Cache) Scrub(checks int) error {
wg.Wait()
}
+ dir = c.base.Append(dirStatus)
+ if entries, readdirErr := os.ReadDir(dir.String()); readdirErr != nil {
+ if !errors.Is(readdirErr, os.ErrNotExist) {
+ addErr(dir, readdirErr)
+ }
+ } else {
+ wg.Add(len(entries))
+ for _, ent := range entries {
+ w <- checkEntry{ent, func(ent os.DirEntry, want *Checksum) bool {
+ got := p.Get().(*Checksum)
+ defer p.Put(got)
+
+ if _, err := os.Stat(c.base.Append(
+ dirIdentifier,
+ ent.Name(),
+ ).String()); err != nil {
+ if !errors.Is(err, os.ErrNotExist) {
+ addErr(dir.Append(ent.Name()), err)
+ }
+ seMu.Lock()
+ se.DanglingStatus = append(se.DanglingStatus, *want)
+ seMu.Unlock()
+ return false
+ }
+ return true
+ }}
+ }
+ wg.Wait()
+ }
+
if len(c.identPending) > 0 {
addErr(c.base, errors.New(
"scrub began with pending artifacts",
@@ -924,6 +964,7 @@ func (c *Cache) Scrub(checks int) error {
if len(se.ChecksumMismatches) > 0 ||
len(se.DanglingIdentifiers) > 0 ||
+ len(se.DanglingStatus) > 0 ||
len(se.Errs) > 0 {
slices.SortFunc(se.ChecksumMismatches, func(a, b ChecksumMismatchError) int {
return bytes.Compare(a.Want[:], b.Want[:])
@@ -931,6 +972,9 @@ func (c *Cache) Scrub(checks int) error {
slices.SortFunc(se.DanglingIdentifiers, func(a, b ID) int {
return bytes.Compare(a[:], b[:])
})
+ slices.SortFunc(se.DanglingStatus, func(a, b ID) int {
+ return bytes.Compare(a[:], b[:])
+ })
return &se
} else {
return nil