@ -38,39 +38,42 @@ func erasureCreateFile(disks []StorageAPI, volume string, path string, partName
// Read until io.EOF, erasure codes data and writes to all disks.
// Read until io.EOF, erasure codes data and writes to all disks.
for {
for {
var n int
var blocks [ ] [ ] byte
var blocks [ ] [ ] byte
n , err = io . ReadFull ( data , buf )
n , rErr := io . ReadFull ( data , buf )
if err == io . EOF {
// FIXME: this is a bug in Golang, n == 0 and err ==
// io.ErrUnexpectedEOF for io.ReadFull function.
if n == 0 && rErr == io . ErrUnexpectedEOF {
return nil , 0 , rErr
}
if rErr == io . EOF {
// We have reached EOF on the first byte read, io.Reader
// We have reached EOF on the first byte read, io.Reader
// must be 0bytes, we don't need to erasure code
// must be 0bytes, we don't need to erasure code
// data. Will create a 0byte file instead.
// data. Will create a 0byte file instead.
if size == 0 {
if size == 0 {
blocks = make ( [ ] [ ] byte , len ( disks ) )
blocks = make ( [ ] [ ] byte , len ( disks ) )
e rr = appendFile ( disks , volume , path , blocks , eInfo . Distribution , hashWriters , writeQuorum )
rE rr = appendFile ( disks , volume , path , blocks , eInfo . Distribution , hashWriters , writeQuorum )
if e rr != nil {
if rE rr != nil {
return nil , 0 , e rr
return nil , 0 , rE rr
}
}
} // else we have reached EOF after few reads, no need to
} // else we have reached EOF after few reads, no need to
// add an additional 0bytes at the end.
// add an additional 0bytes at the end.
break
break
}
}
if e rr != nil && e rr != io . ErrUnexpectedEOF {
if rE rr != nil && rE rr != io . ErrUnexpectedEOF {
return nil , 0 , e rr
return nil , 0 , rE rr
}
}
size += int64 ( n )
// Returns encoded blocks.
// Returns encoded blocks.
var enErr error
var enErr error
blocks , enErr = encodeData ( buf [ : n ] , eInfo . DataBlocks , eInfo . ParityBlocks )
blocks , enErr = encodeData ( buf [ 0 : n ] , eInfo . DataBlocks , eInfo . ParityBlocks )
if enErr != nil {
if enErr != nil {
return nil , 0 , enErr
return nil , 0 , enErr
}
}
// Write to all disks.
// Write to all disks.
err = appendFile ( disks , volume , path , blocks , eInfo . Distribution , hashWriters , writeQuorum )
if err = appendFile ( disks , volume , path , blocks , eInfo . Distribution , hashWriters , writeQuorum ) ; err != nil {
if err != nil {
return nil , 0 , err
return nil , 0 , err
}
}
size += int64 ( n )
}
}
// Save the checksums.
// Save the checksums.