aboutsummaryrefslogtreecommitdiff
path: root/fsck.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-08-15 14:02:05 +0200
committerJakob Unterwurzacher2018-08-15 14:02:05 +0200
commit0e1cbb75fed40d658c72d7fb65c7b012b1b4d31d (patch)
treef9e57f295deb07faababe88df98de21123e7107b /fsck.go
parentdb4accf3a3397e2c5973aa99aae52a8f3e864e27 (diff)
fsck: skip already-seen hard-linked files
We may hit files several times due to hard links. Only check the contents once.
Diffstat (limited to 'fsck.go')
-rw-r--r--fsck.go21
1 files changed, 19 insertions, 2 deletions
diff --git a/fsck.go b/fsck.go
index fb9258c..07e1a88 100644
--- a/fsck.go
+++ b/fsck.go
@@ -26,6 +26,8 @@ type fsckObj struct {
corruptListLock sync.Mutex
// stop a running watchMitigatedCorruptions thread
watchDone chan struct{}
+ // Inode numbers of hard-linked files (Nlink > 1) that we have already checked
+ seenInodes map[uint64]struct{}
}
func (ck *fsckObj) markCorrupt(path string) {
@@ -109,6 +111,20 @@ func (ck *fsckObj) watchMitigatedCorruptionsRead(path string) {
// Check file for corruption
func (ck *fsckObj) file(path string) {
tlog.Debug.Printf("ck.file %q\n", path)
+ attr, status := ck.fs.GetAttr(path, nil)
+ if !status.Ok() {
+ ck.markCorrupt(path)
+ fmt.Printf("fsck: error stating file %q: %v\n", path, status)
+ return
+ }
+ if attr.Nlink > 1 {
+ // Due to hard links, we may have already checked this file.
+ if _, ok := ck.seenInodes[attr.Ino]; ok {
+ tlog.Debug.Printf("ck.file : skipping %q (inode number %d already seen)\n", path, attr.Ino)
+ return
+ }
+ ck.seenInodes[attr.Ino] = struct{}{}
+ }
ck.xattrs(path)
f, status := ck.fs.Open(path, syscall.O_RDONLY, nil)
if !status.Ok() {
@@ -193,8 +209,9 @@ func fsck(args *argContainer) {
fs := pfs.(*fusefrontend.FS)
fs.MitigatedCorruptions = make(chan string)
ck := fsckObj{
- fs: fs,
- watchDone: make(chan struct{}),
+ fs: fs,
+ watchDone: make(chan struct{}),
+ seenInodes: make(map[uint64]struct{}),
}
ck.dir("")
wipeKeys()