@ -30,6 +30,10 @@ func (xl xlObjects) MakeBucket(bucket string) error {
if ! IsValidBucketName ( bucket ) {
if ! IsValidBucketName ( bucket ) {
return BucketNameInvalid { Bucket : bucket }
return BucketNameInvalid { Bucket : bucket }
}
}
// Verify if bucket is found.
if xl . isBucketExist ( bucket ) {
return toObjectErr ( errVolumeExists , bucket )
}
nsMutex . Lock ( bucket , "" )
nsMutex . Lock ( bucket , "" )
defer nsMutex . Unlock ( bucket , "" )
defer nsMutex . Unlock ( bucket , "" )
@ -68,20 +72,36 @@ func (xl xlObjects) MakeBucket(bucket string) error {
}
}
// Verify we have any other errors which should undo make bucket.
// Verify we have any other errors which should undo make bucket.
for _ , err := range dErrs {
if reducedErr := reduceErrs ( dErrs , [ ] error {
// Bucket already exists, return BucketExists error.
errDiskNotFound ,
if err == errVolumeExists {
errFaultyDisk ,
return toObjectErr ( errVolumeExists , bucket )
errDiskAccessDenied ,
}
} ) ; reducedErr != nil {
// Undo make bucket for any other errors.
return toObjectErr ( reducedErr , bucket )
if err != nil && err != errDiskNotFound {
xl . undoMakeBucket ( bucket )
return toObjectErr ( err , bucket )
}
}
}
return nil
return nil
}
}
func ( xl xlObjects ) undoDeleteBucket ( bucket string ) {
// Initialize sync waitgroup.
var wg = & sync . WaitGroup { }
// Undo previous make bucket entry on all underlying storage disks.
for index , disk := range xl . storageDisks {
if disk == nil {
continue
}
wg . Add ( 1 )
// Delete a bucket inside a go-routine.
go func ( index int , disk StorageAPI ) {
defer wg . Done ( )
_ = disk . MakeVol ( bucket )
} ( index , disk )
}
// Wait for all make vol to finish.
wg . Wait ( )
}
// undo make bucket operation upon quorum failure.
// undo make bucket operation upon quorum failure.
func ( xl xlObjects ) undoMakeBucket ( bucket string ) {
func ( xl xlObjects ) undoMakeBucket ( bucket string ) {
// Initialize sync waitgroup.
// Initialize sync waitgroup.
@ -113,7 +133,7 @@ var bucketMetadataOpIgnoredErrs = []error{
// getBucketInfo - returns the BucketInfo from one of the load balanced disks.
// getBucketInfo - returns the BucketInfo from one of the load balanced disks.
func ( xl xlObjects ) getBucketInfo ( bucketName string ) ( bucketInfo BucketInfo , err error ) {
func ( xl xlObjects ) getBucketInfo ( bucketName string ) ( bucketInfo BucketInfo , err error ) {
for _ , disk := range xl . getLoadBalancedQuorum Disks ( ) {
for _ , disk := range xl . getLoadBalancedDisks ( ) {
if disk == nil {
if disk == nil {
continue
continue
}
}
@ -169,7 +189,7 @@ func (xl xlObjects) GetBucketInfo(bucket string) (BucketInfo, error) {
// listBuckets - returns list of all buckets from a disk picked at random.
// listBuckets - returns list of all buckets from a disk picked at random.
func ( xl xlObjects ) listBuckets ( ) ( bucketsInfo [ ] BucketInfo , err error ) {
func ( xl xlObjects ) listBuckets ( ) ( bucketsInfo [ ] BucketInfo , err error ) {
for _ , disk := range xl . getLoadBalancedQuorum Disks ( ) {
for _ , disk := range xl . getLoadBalancedDisks ( ) {
if disk == nil {
if disk == nil {
continue
continue
}
}
@ -220,13 +240,15 @@ func (xl xlObjects) DeleteBucket(bucket string) error {
if ! IsValidBucketName ( bucket ) {
if ! IsValidBucketName ( bucket ) {
return BucketNameInvalid { Bucket : bucket }
return BucketNameInvalid { Bucket : bucket }
}
}
// Verify if bucket is found.
if ! xl . isBucketExist ( bucket ) {
return BucketNotFound { Bucket : bucket }
}
nsMutex . Lock ( bucket , "" )
nsMutex . Lock ( bucket , "" )
defer nsMutex . Unlock ( bucket , "" )
defer nsMutex . Unlock ( bucket , "" )
// Collect if all disks report volume not found.
// Collect if all disks report volume not found.
var volumeNotFoundErrCnt int
var wg = & sync . WaitGroup { }
var wg = & sync . WaitGroup { }
var dErrs = make ( [ ] error , len ( xl . storageDisks ) )
var dErrs = make ( [ ] error , len ( xl . storageDisks ) )
@ -257,21 +279,17 @@ func (xl xlObjects) DeleteBucket(bucket string) error {
// Wait for all the delete vols to finish.
// Wait for all the delete vols to finish.
wg . Wait ( )
wg . Wait ( )
// Count the errors for known errors, return quickly if we found an unknown error.
if ! isDiskQuorum ( dErrs , xl . writeQuorum ) {
for _ , err := range dErrs {
xl . undoDeleteBucket ( bucket )
if err != nil {
return toObjectErr ( errXLWriteQuorum , bucket )
if isErrIgnored ( err , objMetadataOpIgnoredErrs ) {
volumeNotFoundErrCnt ++
continue
}
return toObjectErr ( err , bucket )
}
}
}
// Return errVolumeNotFound if all disks report volume not found.
if reducedErr := reduceErrs ( dErrs , [ ] error {
if volumeNotFoundErrCnt == len ( xl . storageDisks ) {
errFaultyDisk ,
return toObjectErr ( errVolumeNotFound , bucket )
errDiskNotFound ,
errDiskAccessDenied ,
} ) ; reducedErr != nil {
return toObjectErr ( reducedErr , bucket )
}
}
return nil
return nil
}
}