From 6ef0161835c3dd0647830ff5fdf1b59c987624e4 Mon Sep 17 00:00:00 2001 From: "A. Elleuch" Date: Fri, 22 Dec 2017 23:57:57 +0100 Subject: [PATCH] fix: Restore empty files when healing (#5257) HealFile() does not process the case when an empty file is lost in some disks. Since, Reedsolomon erasure doesn't handle restoring empty data, HealFile will create empty files similarly to CreateFile(). --- cmd/erasure-healfile.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/erasure-healfile.go b/cmd/erasure-healfile.go index 952d7aa53..c77922fc9 100644 --- a/cmd/erasure-healfile.go +++ b/cmd/erasure-healfile.go @@ -78,12 +78,14 @@ func (s ErasureStorage) HealFile(staleDisks []StorageAPI, volume, path string, b blocks[i] = make([]byte, chunksize) } var chunkOffset, blockOffset int64 - for ; blockOffset < size; blockOffset += blocksize { + + // The for loop below is entered when size == 0 and + // blockOffset == 0 to allow for reconstructing empty files. + for ; blockOffset == 0 || blockOffset < size; blockOffset += blocksize { // last iteration may have less than blocksize data // left, so chunksize needs to be recomputed. if size < blockOffset+blocksize { - blocksize = size - blockOffset - chunksize = getChunkSize(blocksize, s.dataBlocks) + chunksize = getChunkSize(size-blockOffset, s.dataBlocks) for i := range blocks { blocks[i] = blocks[i][:chunksize] } @@ -121,9 +123,13 @@ func (s ErasureStorage) HealFile(staleDisks []StorageAPI, volume, path string, b // iteration chunkOffset += chunksize - // reconstruct data - this computes all data and parity shards - if err = s.ErasureDecodeDataAndParityBlocks(blocks); err != nil { - return f, err + // reconstruct data - this computes all data and + // parity shards - but we skip this step if we are + // reconstructing an empty file. + if chunksize > 0 { + if err = s.ErasureDecodeDataAndParityBlocks(blocks); err != nil { + return f, err + } } // write computed shards as chunks on file in each