2021-04-19 03:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (c) 2015-2021 MinIO, Inc.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of MinIO Object Storage stack
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 04:49:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-06 23:52:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/madmin-go" 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 04:49:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/logger" 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// BucketQuotaSys - map of bucket and quota configuration.
  
						 
					
						
							
								
									
										
										
										
											2020-05-27 21:45:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  BucketQuotaSys  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketStorageCache  timedValue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Get - Get quota configuration.
  
						 
					
						
							
								
									
										
										
										
											2022-02-01 09:27:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sys  * BucketQuotaSys )  Get ( ctx  context . Context ,  bucketName  string )  ( * madmin . BucketQuota ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									qCfg ,  _ ,  err  :=  globalBucketMetadataSys . GetQuotaConfig ( ctx ,  bucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  qCfg ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewBucketQuotaSys returns initialized BucketQuotaSys
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewBucketQuotaSys ( )  * BucketQuotaSys  {  
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & BucketQuotaSys { } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 03:07:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Init initialize bucket quota.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sys  * BucketQuotaSys )  Init ( objAPI  ObjectLayer )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sys . bucketStorageCache . Once . Do ( func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sys . bucketStorageCache . TTL  =  1  *  time . Second 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sys . bucketStorageCache . Update  =  func ( )  ( interface { } ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ctx ,  done  :=  context . WithTimeout ( context . Background ( ) ,  5 * time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  loadDataUsageFromBackend ( ctx ,  objAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetBucketUsageInfo return bucket usage info for a given bucket
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sys  * BucketQuotaSys )  GetBucketUsageInfo ( bucket  string )  ( BucketUsageInfo ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v ,  err  :=  sys . bucketStorageCache . Get ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  BucketUsageInfo { } ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dui ,  ok  :=  v . ( DataUsageInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  BucketUsageInfo { } ,  fmt . Errorf ( "internal error: Unexpected DUI data type: %T" ,  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bui  :=  dui . BucketsUsage [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  bui ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// parseBucketQuota parses BucketQuota from json
  
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseBucketQuota ( bucket  string ,  data  [ ] byte )  ( quotaCfg  * madmin . BucketQuota ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									quotaCfg  =  & madmin . BucketQuota { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  json . Unmarshal ( data ,  quotaCfg ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  quotaCfg ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! quotaCfg . IsValid ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 04:49:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  quotaCfg . Type  ==  "fifo"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . LogIf ( GlobalContext ,  errors . New ( "Detected older 'fifo' quota config, 'fifo' feature is removed and not supported anymore. Please clear your quota configs using 'mc admin bucket quota alias/bucket --clear' and use 'mc ilm add' for expiration of objects" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  quotaCfg ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  quotaCfg ,  fmt . Errorf ( "Invalid quota config %#v" ,  quotaCfg ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 03:07:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sys  * BucketQuotaSys )  enforceQuotaHard ( ctx  context . Context ,  bucket  string ,  size  int64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  size  <  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 21:45:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 09:27:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									q ,  err  :=  sys . Get ( ctx ,  bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 21:45:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-25 03:24:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  q  !=  nil  &&  q . Type  ==  madmin . HardQuota  &&  q . Quota  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 03:07:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bui ,  err  :=  sys . GetBucketUsageInfo ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-25 03:24:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 21:45:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 03:07:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  bui . Size  >  0  &&  ( ( bui . Size  +  uint64 ( size ) )  >=  q . Quota )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-25 03:24:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  BucketQuotaExceeded { Bucket :  bucket } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 21:45:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-27 21:45:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 03:07:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  enforceBucketQuotaHard ( ctx  context . Context ,  bucket  string ,  size  int64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalBucketQuotaSys  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 03:07:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  globalBucketQuotaSys . enforceQuotaHard ( ctx ,  bucket ,  size ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 06:55:54 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}