2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  MinIO  Cloud  Storage ,  ( C )  2017  MinIO ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2018-07-31 15:23:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// metadata entry for storage class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									amzStorageClass  =  "x-amz-storage-class" 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Canonical metadata entry for storage class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									amzStorageClassCanonical  =  "X-Amz-Storage-Class" 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Reduced redundancy storage class
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reducedRedundancyStorageClass  =  "REDUCED_REDUNDANCY" 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Standard storage class
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									standardStorageClass  =  "STANDARD" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Reduced redundancy storage class environment variable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reducedRedundancyStorageClassEnv  =  "MINIO_STORAGE_CLASS_RRS" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Standard storage class environment variable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									standardStorageClassEnv  =  "MINIO_STORAGE_CLASS_STANDARD" 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Supported storage class scheme is EC
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									supportedStorageClassScheme  =  "EC" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Minimum parity disks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									minimumParityDisks  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defaultRRSParity    =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Struct to hold storage class
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  storageClass  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Scheme  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Parity  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  storageClassConfig  struct  {  
						 
					
						
							
								
									
										
										
										
											2018-01-09 14:26:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Standard  storageClass  ` json:"standard" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RRS       storageClass  ` json:"rrs" ` 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Validate SS and RRS parity when unmarshalling JSON.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sCfg  * storageClassConfig )  UnmarshalJSON ( data  [ ] byte )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  Alias  storageClassConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									aux  :=  & struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* Alias 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Alias :  ( * Alias ) ( sCfg ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  json . Unmarshal ( data ,  & aux ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  validateParity ( aux . Standard . Parity ,  aux . RRS . Parity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Validate if storage class in metadata
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Only Standard and RRS Storage classes are supported
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isValidStorageClassMeta ( sc  string )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sc  ==  reducedRedundancyStorageClass  ||  sc  ==  standardStorageClass 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 14:26:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sc  * storageClass )  UnmarshalText ( b  [ ] byte )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scStr  :=  string ( b ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  scStr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 14:26:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s ,  err  :=  parseStorageClass ( scStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sc . Parity  =  s . Parity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sc . Scheme  =  s . Scheme 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 14:26:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sc  * storageClass )  MarshalText ( )  ( [ ] byte ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sc . Scheme  !=  ""  &&  sc . Parity  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  [ ] byte ( fmt . Sprintf ( "%s:%d" ,  sc . Scheme ,  sc . Parity ) ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  [ ] byte ( "" ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Parses given storageClassEnv and returns a storageClass structure.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Supported Storage Class format is "Scheme:Number of parity disks".
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Currently only supported scheme is "EC".
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseStorageClass ( storageClassEnv  string )  ( sc  storageClass ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  strings . Split ( storageClassEnv ,  ":" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// only two elements allowed in the string - "scheme" and "number of parity disks"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( s )  >  2  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-09 10:04:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  storageClass { } ,  uiErrStorageClassValue ( nil ) . Msg ( "Too many sections in "  +  storageClassEnv ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  if  len ( s )  <  2  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-09 10:04:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  storageClass { } ,  uiErrStorageClassValue ( nil ) . Msg ( "Too few sections in "  +  storageClassEnv ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// only allowed scheme is "EC"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s [ 0 ]  !=  supportedStorageClassScheme  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-09 10:04:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  storageClass { } ,  uiErrStorageClassValue ( nil ) . Msg ( "Unsupported scheme "  +  s [ 0 ]  +  ". Supported scheme is EC" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Number of parity disks should be integer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parityDisks ,  err  :=  strconv . Atoi ( s [ 1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-09 10:04:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  storageClass { } ,  uiErrStorageClassValue ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sc  =  storageClass { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Scheme :  s [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Parity :  parityDisks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sc ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Validates the parity disks.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  validateParity ( ssParity ,  rrsParity  int )  ( err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ssParity  ==  0  &&  rrsParity  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIsXL  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 14:26:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Setting storage class only allowed for erasure coding mode" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// SS parity disks should be greater than or equal to minimumParityDisks. Parity below minimumParityDisks is not recommended.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ssParity  >  0  &&  ssParity  <  minimumParityDisks  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Standard storage class parity %d should be greater than or equal to %d" ,  ssParity ,  minimumParityDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// RRS parity disks should be greater than or equal to minimumParityDisks. Parity below minimumParityDisks is not recommended.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rrsParity  >  0  &&  rrsParity  <  minimumParityDisks  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Reduced redundancy storage class parity %d should be greater than or equal to %d" ,  rrsParity ,  minimumParityDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ssParity  >  globalXLSetDriveCount / 2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Standard storage class parity %d should be less than or equal to %d" ,  ssParity ,  globalXLSetDriveCount / 2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rrsParity  >  globalXLSetDriveCount / 2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Reduced redundancy storage class parity %d should be less than  or equal to %d" ,  rrsParity ,  globalXLSetDriveCount / 2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 14:26:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 15:30:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ssParity  >  0  &&  rrsParity  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ssParity  <  rrsParity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  fmt . Errorf ( "Standard storage class parity disks %d should be greater than or equal to Reduced redundancy storage class parity disks %d" ,  ssParity ,  rrsParity ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns the data and parity drive count based on storage class
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If storage class is set using the env vars MINIO_STORAGE_CLASS_RRS and MINIO_STORAGE_CLASS_STANDARD
  
						 
					
						
							
								
									
										
										
										
											2018-01-11 17:28:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// or config.json fields
  
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// -- corresponding values are returned
  
						 
					
						
							
								
									
										
										
										
											2018-01-11 17:28:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If storage class is not set during startup, default values are returned
  
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// -- Default for Reduced Redundancy Storage class is, parity = 2 and data = N-Parity
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// -- Default for Standard Storage class is, parity = N/2, data = N/2
  
						 
					
						
							
								
									
										
										
										
											2018-01-11 17:28:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If storage class is empty
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// -- standard storage class is assumed and corresponding data and parity is returned
  
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getRedundancyCount ( sc  string ,  totalDisks  int )  ( data ,  parity  int )  {  
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									parity  =  totalDisks  /  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  sc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  reducedRedundancyStorageClass : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  globalRRStorageClass . Parity  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// set the rrs parity if available
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parity  =  globalRRStorageClass . Parity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// else fall back to default value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parity  =  defaultRRSParity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-11 17:28:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  standardStorageClass ,  "" : 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  globalStandardStorageClass . Parity  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// set the standard parity if available
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parity  =  globalStandardStorageClass . Parity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// data is always totalDisks - parity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  totalDisks  -  parity ,  parity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns per object readQuorum and writeQuorum
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// readQuorum is the minimum required disks to read data.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// writeQuorum is the minimum required disks to write data.
  
						 
					
						
							
								
									
										
										
										
											2018-07-31 15:23:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  objectQuorumFromMeta ( ctx  context . Context ,  xl  xlObjects ,  partsMetaData  [ ] xlMetaV1 ,  errs  [ ] error )  ( objectReadQuorum ,  objectWriteQuorum  int ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// get the latest updated Metadata and a count of all the latest updated xlMeta(s)
 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-31 15:23:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latestXLMeta ,  err  :=  getLatestXLMeta ( ctx ,  partsMetaData ,  errs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  0 ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Since all the valid erasure code meta updated at the same time are equivalent, pass dataBlocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// from latestXLMeta to get the quorum
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  latestXLMeta . Erasure . DataBlocks ,  latestXLMeta . Erasure . DataBlocks  +  1 ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}