diff options
| author | Jakob Unterwurzacher | 2018-07-01 16:24:02 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2018-07-01 20:56:22 +0200 | 
| commit | 4a736377829f9b72a538d9f1e75ccc4defddc69a (patch) | |
| tree | 397eec85daeadf572309b81f6fc36d2549dd7b07 | |
| parent | 1a18d8e6098633f27c228f6ebce8881a061df54c (diff) | |
fsck: get rid of channel read closures
Create proper functions instead to declutter the logic.
| -rw-r--r-- | fsck.go | 96 | 
1 files changed, 55 insertions, 41 deletions
| @@ -22,6 +22,8 @@ type fsckObj struct {  	corruptList []string  	// Protects corruptList  	corruptListLock sync.Mutex +	// stop a running watchMitigatedCorruptions thread +	watchDone chan struct{}  }  func (ck *fsckObj) markCorrupt(path string) { @@ -30,24 +32,28 @@ func (ck *fsckObj) markCorrupt(path string) {  	ck.corruptListLock.Unlock()  } +// Watch for mitigated corruptions that occour during OpenDir() +func (ck *fsckObj) watchMitigatedCorruptionsOpenDir(path string) { +	for { +		select { +		case item := <-ck.fs.MitigatedCorruptions: +			fmt.Printf("fsck: corrupt entry in dir %q: %q\n", path, item) +			ck.markCorrupt(filepath.Join(path, item)) +		case <-ck.watchDone: +			return +		} +	} +} +  // Recursively check dir for corruption  func (ck *fsckObj) dir(path string) {  	//fmt.Printf("ck.dir %q\n", path)  	ck.xattrs(path) -	done := make(chan struct{}) -	go func() { -		for { -			select { -			case item := <-ck.fs.MitigatedCorruptions: -				fmt.Printf("fsck: corrupt entry in dir %q: %q\n", path, item) -				ck.markCorrupt(filepath.Join(path, item)) -			case <-done: -				return -			} -		} -	}() +	// Run OpenDir and catch transparently mitigated corruptions +	go ck.watchMitigatedCorruptionsOpenDir(path)  	entries, status := ck.fs.OpenDir(path, nil) -	done <- struct{}{} +	ck.watchDone <- struct{}{} +	// Also catch non-mitigated corruptions  	if !status.Ok() {  		ck.markCorrupt(path)  		fmt.Printf("fsck: error opening dir %q: %v\n", path, status) @@ -85,7 +91,20 @@ func (ck *fsckObj) symlink(path string) {  	}  } -// check file for corruption +// Watch for mitigated corruptions that occour during Read() +func (ck *fsckObj) watchMitigatedCorruptionsRead(path string) { +	for { +		select { +		case item := <-ck.fs.MitigatedCorruptions: +			fmt.Printf("fsck: corrupt file %q (inode %s)\n", path, item) +			ck.markCorrupt(path) +		case <-ck.watchDone: +			return +		} +	} +} + +// Check file for corruption  func (ck *fsckObj) file(path string) {  	//fmt.Printf("ck.file %q\n", path)  	ck.xattrs(path) @@ -98,19 +117,9 @@ func (ck *fsckObj) file(path string) {  	defer f.Release()  	buf := make([]byte, fuse.MAX_KERNEL_WRITE)  	var off int64 -	done := make(chan struct{}) -	go func() { -		for { -			select { -			case item := <-ck.fs.MitigatedCorruptions: -				fmt.Printf("fsck: corrupt file %q (inode %s)\n", path, item) -				ck.markCorrupt(path) -			case <-done: -				return -			} -		} -	}() -	defer func() { done <- struct{}{} }() +	// Read() through the whole file and catch transparently mitigated corruptions +	go ck.watchMitigatedCorruptionsRead(path) +	defer func() { ck.watchDone <- struct{}{} }()  	for {  		result, status := f.Read(buf, off)  		if !status.Ok() { @@ -126,22 +135,26 @@ func (ck *fsckObj) file(path string) {  	}  } +// Watch for mitigated corruptions that occour during ListXAttr() +func (ck *fsckObj) watchMitigatedCorruptionsListXAttr(path string) { +	for { +		select { +		case item := <-ck.fs.MitigatedCorruptions: +			fmt.Printf("fsck: corrupt xattr name on file %q: %q\n", path, item) +			ck.markCorrupt(path + " xattr:" + item) +		case <-ck.watchDone: +			return +		} +	} +} +  // Check xattrs on file/dir at path  func (ck *fsckObj) xattrs(path string) { -	done := make(chan struct{}) -	go func() { -		for { -			select { -			case item := <-ck.fs.MitigatedCorruptions: -				fmt.Printf("fsck: corrupt xattr name on file %q: %q\n", path, item) -				ck.markCorrupt(path + " xattr:" + item) -			case <-done: -				return -			} -		} -	}() +	// Run ListXAttr() and catch transparently mitigated corruptions +	go ck.watchMitigatedCorruptionsListXAttr(path)  	attrs, status := ck.fs.ListXAttr(path, nil) -	done <- struct{}{} +	ck.watchDone <- struct{}{} +	// Also catch non-mitigated corruptions  	if !status.Ok() {  		fmt.Printf("fsck: error listing xattrs on %q: %v\n", path, status)  		ck.markCorrupt(path) @@ -166,7 +179,8 @@ func fsck(args *argContainer) {  	fs := pfs.(*fusefrontend.FS)  	fs.MitigatedCorruptions = make(chan string)  	ck := fsckObj{ -		fs: fs, +		fs:        fs, +		watchDone: make(chan struct{}),  	}  	ck.dir("")  	wipeKeys() | 
