diff options
| author | Jakob Unterwurzacher | 2018-08-15 14:02:05 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2018-08-15 14:02:05 +0200 | 
| commit | 0e1cbb75fed40d658c72d7fb65c7b012b1b4d31d (patch) | |
| tree | f9e57f295deb07faababe88df98de21123e7107b | |
| parent | db4accf3a3397e2c5973aa99aae52a8f3e864e27 (diff) | |
fsck: skip already-seen hard-linked files
We may hit files several times due to hard links.
Only check the contents once.
| -rw-r--r-- | fsck.go | 21 | 
1 files changed, 19 insertions, 2 deletions
| @@ -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() | 
