mirror of
				https://github.com/minio/minio.git
				synced 2025-10-30 00:05:02 -04:00 
			
		
		
		
	
							parent
							
								
									36e88cbd50
								
							
						
					
					
						commit
						d9e7cadacf
					
				| @ -18,6 +18,7 @@ package cmd | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/klauspost/reedsolomon" | ||||
| 	"github.com/minio/minio/cmd/logger" | ||||
| @ -25,7 +26,7 @@ import ( | ||||
| 
 | ||||
| // Erasure - erasure encoding details. | ||||
| type Erasure struct { | ||||
| 	encoder                  reedsolomon.Encoder | ||||
| 	encoder                  func() reedsolomon.Encoder | ||||
| 	dataBlocks, parityBlocks int | ||||
| 	blockSize                int64 | ||||
| } | ||||
| @ -37,10 +38,29 @@ func NewErasure(ctx context.Context, dataBlocks, parityBlocks int, blockSize int | ||||
| 		parityBlocks: parityBlocks, | ||||
| 		blockSize:    blockSize, | ||||
| 	} | ||||
| 	e.encoder, err = reedsolomon.New(dataBlocks, parityBlocks, reedsolomon.WithAutoGoroutines(int(e.ShardSize()))) | ||||
| 	if err != nil { | ||||
| 		logger.LogIf(ctx, err) | ||||
| 		return e, err | ||||
| 
 | ||||
| 	// Check the parameters for sanity now. | ||||
| 	if dataBlocks <= 0 || parityBlocks <= 0 { | ||||
| 		return e, reedsolomon.ErrInvShardNum | ||||
| 	} | ||||
| 
 | ||||
| 	if dataBlocks+parityBlocks > 256 { | ||||
| 		return e, reedsolomon.ErrMaxShardNum | ||||
| 	} | ||||
| 
 | ||||
| 	// Encoder when needed. | ||||
| 	var enc reedsolomon.Encoder | ||||
| 	var once sync.Once | ||||
| 	e.encoder = func() reedsolomon.Encoder { | ||||
| 		once.Do(func() { | ||||
| 			e, err := reedsolomon.New(dataBlocks, parityBlocks, reedsolomon.WithAutoGoroutines(int(e.ShardSize()))) | ||||
| 			if err != nil { | ||||
| 				// Error conditions should be checked above. | ||||
| 				panic(err) | ||||
| 			} | ||||
| 			enc = e | ||||
| 		}) | ||||
| 		return enc | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| @ -51,12 +71,12 @@ func (e *Erasure) EncodeData(ctx context.Context, data []byte) ([][]byte, error) | ||||
| 	if len(data) == 0 { | ||||
| 		return make([][]byte, e.dataBlocks+e.parityBlocks), nil | ||||
| 	} | ||||
| 	encoded, err := e.encoder.Split(data) | ||||
| 	encoded, err := e.encoder().Split(data) | ||||
| 	if err != nil { | ||||
| 		logger.LogIf(ctx, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err = e.encoder.Encode(encoded); err != nil { | ||||
| 	if err = e.encoder().Encode(encoded); err != nil { | ||||
| 		logger.LogIf(ctx, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| @ -77,13 +97,23 @@ func (e *Erasure) DecodeDataBlocks(data [][]byte) error { | ||||
| 	if !needsReconstruction { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return e.encoder.ReconstructData(data) | ||||
| 	return e.encoder().ReconstructData(data) | ||||
| } | ||||
| 
 | ||||
| // DecodeDataAndParityBlocks decodes the given erasure-coded data and verifies it. | ||||
| // It returns an error if the decoding failed. | ||||
| func (e *Erasure) DecodeDataAndParityBlocks(ctx context.Context, data [][]byte) error { | ||||
| 	if err := e.encoder.Reconstruct(data); err != nil { | ||||
| 	needsReconstruction := false | ||||
| 	for _, b := range data { | ||||
| 		if b == nil { | ||||
| 			needsReconstruction = true | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	if !needsReconstruction { | ||||
| 		return nil | ||||
| 	} | ||||
| 	if err := e.encoder().Reconstruct(data); err != nil { | ||||
| 		logger.LogIf(ctx, err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @ -171,20 +171,15 @@ func disksWithAllParts(ctx context.Context, onlineDisks []StorageAPI, partsMetad | ||||
| 
 | ||||
| 		switch scanMode { | ||||
| 		case madmin.HealDeepScan: | ||||
| 			erasureInfo := partsMetadata[i].Erasure | ||||
| 			erasure, err := NewErasure(ctx, erasureInfo.DataBlocks, erasureInfo.ParityBlocks, erasureInfo.BlockSize) | ||||
| 			if err != nil { | ||||
| 				dataErrs[i] = err | ||||
| 				continue | ||||
| 			} | ||||
| 			erasure := partsMetadata[i].Erasure | ||||
| 
 | ||||
| 			// disk has a valid xl.json but may not have all the | ||||
| 			// parts. This is considered an outdated disk, since | ||||
| 			// it needs healing too. | ||||
| 			for _, part := range partsMetadata[i].Parts { | ||||
| 				checksumInfo := erasureInfo.GetChecksumInfo(part.Number) | ||||
| 				checksumInfo := erasure.GetChecksumInfo(part.Number) | ||||
| 				partPath := pathJoin(object, fmt.Sprintf("part.%d", part.Number)) | ||||
| 				err = onlineDisk.VerifyFile(bucket, partPath, erasure.ShardFileSize(part.Size), checksumInfo.Algorithm, checksumInfo.Hash, erasure.ShardSize()) | ||||
| 				err := onlineDisk.VerifyFile(bucket, partPath, erasure.ShardFileSize(part.Size), checksumInfo.Algorithm, checksumInfo.Hash, erasure.ShardSize()) | ||||
| 				if err != nil { | ||||
| 					if !IsErr(err, []error{ | ||||
| 						errFileNotFound, | ||||
|  | ||||
| @ -139,6 +139,25 @@ func (e ErasureInfo) GetChecksumInfo(partNumber int) (ckSum ChecksumInfo) { | ||||
| 	return ChecksumInfo{} | ||||
| } | ||||
| 
 | ||||
| // ShardFileSize - returns final erasure size from original size. | ||||
| func (e ErasureInfo) ShardFileSize(totalLength int64) int64 { | ||||
| 	if totalLength == 0 { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	if totalLength == -1 { | ||||
| 		return -1 | ||||
| 	} | ||||
| 	numShards := totalLength / e.BlockSize | ||||
| 	lastBlockSize := totalLength % e.BlockSize | ||||
| 	lastShardSize := ceilFrac(lastBlockSize, int64(e.DataBlocks)) | ||||
| 	return numShards*e.ShardSize() + lastShardSize | ||||
| } | ||||
| 
 | ||||
| // ShardSize - returns actual shared size from erasure blockSize. | ||||
| func (e ErasureInfo) ShardSize() int64 { | ||||
| 	return ceilFrac(e.BlockSize, int64(e.DataBlocks)) | ||||
| } | ||||
| 
 | ||||
| // statInfo - carries stat information of the object. | ||||
| type statInfo struct { | ||||
| 	Size    int64     `json:"size"`    // Size of the object `xl.json`. | ||||
|  | ||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @ -51,10 +51,10 @@ require ( | ||||
| 	github.com/jonboulle/clockwork v0.1.0 // indirect | ||||
| 	github.com/json-iterator/go v1.1.9 | ||||
| 	github.com/klauspost/compress v1.10.3 | ||||
| 	github.com/klauspost/cpuid v1.2.2 | ||||
| 	github.com/klauspost/cpuid v1.2.4 | ||||
| 	github.com/klauspost/pgzip v1.2.1 | ||||
| 	github.com/klauspost/readahead v1.3.1 | ||||
| 	github.com/klauspost/reedsolomon v1.9.3 | ||||
| 	github.com/klauspost/reedsolomon v1.9.7 | ||||
| 	github.com/lib/pq v1.1.1 | ||||
| 	github.com/mattn/go-colorable v0.1.1 | ||||
| 	github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb // indirect | ||||
|  | ||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							| @ -218,12 +218,16 @@ github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eT | ||||
| github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= | ||||
| github.com/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us= | ||||
| github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/klauspost/cpuid v1.2.4 h1:EBfaK0SWSwk+fgk6efYFWdzl8MwRWoOO1gkmiaTXPW4= | ||||
| github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM= | ||||
| github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= | ||||
| github.com/klauspost/readahead v1.3.1 h1:QqXNYvm+VvqYcbrRT4LojUciM0XrznFRIDrbHiJtu/0= | ||||
| github.com/klauspost/readahead v1.3.1/go.mod h1:AH9juHzNH7xqdqFHrMRSHeH2Ps+vFf+kblDqzPFiLJg= | ||||
| github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY= | ||||
| github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= | ||||
| github.com/klauspost/reedsolomon v1.9.7 h1:+azeqnT4iNG9UEcWC+7utJ4xXQ9S8pSlkZor0DOArEQ= | ||||
| github.com/klauspost/reedsolomon v1.9.7/go.mod h1:+8WD025Xpby8/kG5h/HDPIFhiiuGEtZOKw+5Y4drAD8= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user