fix: do not niladic p.writers upon failure (#12255)

p.writers is a verbatim value of bitrotWriter
backed by a pipe() that should never be nil'ed,
instead use the captured errors to skip the writes.

additionally detect also short writes, and reject
them as errors.
This commit is contained in:
Harshavardhana 2021-05-10 08:20:23 -07:00 committed by GitHub
parent 8b52d70012
commit 2d79d6d847
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -42,13 +42,18 @@ func (p *parallelWriter) Write(ctx context.Context, blocks [][]byte) error {
p.errs[i] = errDiskNotFound p.errs[i] = errDiskNotFound
continue continue
} }
if p.errs[i] != nil {
continue
}
wg.Add(1) wg.Add(1)
go func(i int) { go func(i int) {
defer wg.Done() defer wg.Done()
_, p.errs[i] = p.writers[i].Write(blocks[i]) var n int
if p.errs[i] != nil { n, p.errs[i] = p.writers[i].Write(blocks[i])
p.writers[i] = nil if p.errs[i] == nil {
if n != len(blocks[i]) {
p.errs[i] = io.ErrShortWrite
}
} }
}(i) }(i)
} }
@ -58,12 +63,7 @@ func (p *parallelWriter) Write(ctx context.Context, blocks [][]byte) error {
// CreateFile with p.writeQuorum=1 to accommodate healing of single disk. // CreateFile with p.writeQuorum=1 to accommodate healing of single disk.
// i.e if we do no return here in such a case, reduceWriteQuorumErrs() would // i.e if we do no return here in such a case, reduceWriteQuorumErrs() would
// return a quorum error to HealFile(). // return a quorum error to HealFile().
nilCount := 0 nilCount := countErrs(p.errs, nil)
for _, err := range p.errs {
if err == nil {
nilCount++
}
}
if nilCount >= p.writeQuorum { if nilCount >= p.writeQuorum {
return nil return nil
} }