@ -94,7 +94,7 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
eof = true
break
}
return ListMultipartsInfo { } , err
return ListMultipartsInfo { } , walkResult . err
}
entry := strings . TrimPrefix ( walkResult . entry , retainSlash ( pathJoin ( mpartMetaPrefix , bucket ) ) )
if strings . HasSuffix ( walkResult . entry , slashSeparator ) {
@ -176,42 +176,42 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
func ( fs fsObjects ) ListMultipartUploads ( bucket , prefix , keyMarker , uploadIDMarker , delimiter string , maxUploads int ) ( ListMultipartsInfo , error ) {
// Validate input arguments.
if ! IsValidBucketName ( bucket ) {
return ListMultipartsInfo { } , BucketNameInvalid { Bucket : bucket }
return ListMultipartsInfo { } , traceError ( BucketNameInvalid { Bucket : bucket } )
}
if ! fs . isBucketExist ( bucket ) {
return ListMultipartsInfo { } , BucketNotFound { Bucket : bucket }
return ListMultipartsInfo { } , traceError ( BucketNotFound { Bucket : bucket } )
}
if ! IsValidObjectPrefix ( prefix ) {
return ListMultipartsInfo { } , ObjectNameInvalid { Bucket : bucket , Object : prefix }
return ListMultipartsInfo { } , traceError ( ObjectNameInvalid { Bucket : bucket , Object : prefix } )
}
// Verify if delimiter is anything other than '/', which we do not support.
if delimiter != "" && delimiter != slashSeparator {
return ListMultipartsInfo { } , UnsupportedDelimiter {
return ListMultipartsInfo { } , traceError ( UnsupportedDelimiter {
Delimiter : delimiter ,
}
} )
}
// Verify if marker has prefix.
if keyMarker != "" && ! strings . HasPrefix ( keyMarker , prefix ) {
return ListMultipartsInfo { } , InvalidMarkerPrefixCombination {
return ListMultipartsInfo { } , traceError ( InvalidMarkerPrefixCombination {
Marker : keyMarker ,
Prefix : prefix ,
}
} )
}
if uploadIDMarker != "" {
if strings . HasSuffix ( keyMarker , slashSeparator ) {
return ListMultipartsInfo { } , InvalidUploadIDKeyCombination {
return ListMultipartsInfo { } , traceError ( InvalidUploadIDKeyCombination {
UploadIDMarker : uploadIDMarker ,
KeyMarker : keyMarker ,
}
} )
}
id , err := uuid . Parse ( uploadIDMarker )
if err != nil {
return ListMultipartsInfo { } , err
return ListMultipartsInfo { } , traceError ( err )
}
if id . IsZero ( ) {
return ListMultipartsInfo { } , MalformedUploadID {
return ListMultipartsInfo { } , traceError ( MalformedUploadID {
UploadID : uploadIDMarker ,
}
} )
}
}
return fs . listMultipartUploads ( bucket , prefix , keyMarker , uploadIDMarker , delimiter , maxUploads )
@ -247,9 +247,9 @@ func (fs fsObjects) newMultipartUpload(bucket string, object string, meta map[st
if err = fs . writeUploadJSON ( bucket , object , uploadID , initiated ) ; err != nil {
return "" , err
}
fsMeta Path := path . Join ( mpartMetaPrefix , bucket , object , uploadID , fsMetaJSONFile )
if err = writeFSMetadata ( fs . storage , minioMetaBucket , fsMetaPath , fsMeta ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , fsMeta Path)
uploadID Path := path . Join ( mpartMetaPrefix , bucket , object , uploadID )
if err = writeFSMetadata ( fs . storage , minioMetaBucket , path . Join ( uploadIDPath , fsMetaJSONFile ) , fsMeta ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , uploadID Path)
}
// Return success.
return uploadID , nil
@ -263,15 +263,15 @@ func (fs fsObjects) newMultipartUpload(bucket string, object string, meta map[st
func ( fs fsObjects ) NewMultipartUpload ( bucket , object string , meta map [ string ] string ) ( string , error ) {
// Verify if bucket name is valid.
if ! IsValidBucketName ( bucket ) {
return "" , BucketNameInvalid { Bucket : bucket }
return "" , traceError ( BucketNameInvalid { Bucket : bucket } )
}
// Verify whether the bucket exists.
if ! fs . isBucketExist ( bucket ) {
return "" , BucketNotFound { Bucket : bucket }
return "" , traceError ( BucketNotFound { Bucket : bucket } )
}
// Verify if object name is valid.
if ! IsValidObjectName ( object ) {
return "" , ObjectNameInvalid { Bucket : bucket , Object : object }
return "" , traceError ( ObjectNameInvalid { Bucket : bucket , Object : object } )
}
return fs . newMultipartUpload ( bucket , object , meta )
}
@ -404,14 +404,14 @@ func appendParts(disk StorageAPI, bucket, object, uploadID, opsID string) {
func ( fs fsObjects ) PutObjectPart ( bucket , object , uploadID string , partID int , size int64 , data io . Reader , md5Hex string ) ( string , error ) {
// Verify if bucket is valid.
if ! IsValidBucketName ( bucket ) {
return "" , BucketNameInvalid { Bucket : bucket }
return "" , traceError ( BucketNameInvalid { Bucket : bucket } )
}
// Verify whether the bucket exists.
if ! fs . isBucketExist ( bucket ) {
return "" , BucketNotFound { Bucket : bucket }
return "" , traceError ( BucketNotFound { Bucket : bucket } )
}
if ! IsValidObjectName ( object ) {
return "" , ObjectNameInvalid { Bucket : bucket , Object : object }
return "" , traceError ( ObjectNameInvalid { Bucket : bucket , Object : object } )
}
uploadIDPath := path . Join ( mpartMetaPrefix , bucket , object , uploadID )
@ -425,7 +425,7 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
uploadIDExists := fs . isUploadIDExists ( bucket , object , uploadID )
nsMutex . RUnlock ( minioMetaBucket , uploadIDPath , opsID )
if ! uploadIDExists {
return "" , InvalidUploadID { UploadID : uploadID }
return "" , traceError ( InvalidUploadID { UploadID : uploadID } )
}
partSuffix := fmt . Sprintf ( "object%d" , partID )
@ -459,7 +459,7 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
// bytes than specified in request header.
if bytesWritten < size {
fs . storage . DeleteFile ( minioMetaBucket , tmpPartPath )
return "" , IncompleteBody { }
return "" , traceError ( IncompleteBody { } )
}
// Validate if payload is valid.
@ -468,7 +468,7 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
// Incoming payload wrong, delete the temporary object.
fs . storage . DeleteFile ( minioMetaBucket , tmpPartPath )
// Error return.
return "" , toObjectErr ( err , bucket , object )
return "" , toObjectErr ( traceError ( err ) , bucket , object )
}
}
@ -478,7 +478,7 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
// MD5 mismatch, delete the temporary object.
fs . storage . DeleteFile ( minioMetaBucket , tmpPartPath )
// Returns md5 mismatch.
return "" , BadDigest { md5Hex , newMD5Hex }
return "" , traceError ( BadDigest { md5Hex , newMD5Hex } )
}
}
@ -492,7 +492,7 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
// Just check if the uploadID exists to avoid copy if it doesn't.
if ! fs . isUploadIDExists ( bucket , object , uploadID ) {
return "" , InvalidUploadID { UploadID : uploadID }
return "" , traceError ( InvalidUploadID { UploadID : uploadID } )
}
fsMetaPath := pathJoin ( uploadIDPath , fsMetaJSONFile )
@ -506,13 +506,13 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
err = fs . storage . RenameFile ( minioMetaBucket , tmpPartPath , minioMetaBucket , partPath )
if err != nil {
if dErr := fs . storage . DeleteFile ( minioMetaBucket , tmpPartPath ) ; dErr != nil {
return "" , toObjectErr ( dErr , minioMetaBucket , tmpPartPath )
return "" , toObjectErr ( traceError ( dErr ) , minioMetaBucket , tmpPartPath )
}
return "" , toObjectErr ( err , minioMetaBucket , partPath )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , partPath )
}
if err = writeFSMetadata ( fs . storage , minioMetaBucket , fsMetaPath , fsMeta ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , fsMeta Path)
uploadIDPath = path . Join ( mpartMetaPrefix , bucket , object , uploadID )
if err = writeFSMetadata ( fs . storage , minioMetaBucket , path . Join ( uploadIDPath , fsMetaJSONFile ) , fsMeta ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , uploadID Path)
}
go appendParts ( fs . storage , bucket , object , uploadID , opsID )
return newMD5Hex , nil
@ -541,7 +541,7 @@ func (fs fsObjects) listObjectParts(bucket, object, uploadID string, partNumberM
partNamePath := path . Join ( mpartMetaPrefix , bucket , object , uploadID , part . Name )
fi , err = fs . storage . StatFile ( minioMetaBucket , partNamePath )
if err != nil {
return ListPartsInfo { } , toObjectErr ( err , minioMetaBucket , partNamePath )
return ListPartsInfo { } , toObjectErr ( traceError ( err ) , minioMetaBucket , partNamePath )
}
result . Parts = append ( result . Parts , partInfo {
PartNumber : part . Number ,
@ -579,14 +579,14 @@ func (fs fsObjects) listObjectParts(bucket, object, uploadID string, partNumberM
func ( fs fsObjects ) ListObjectParts ( bucket , object , uploadID string , partNumberMarker , maxParts int ) ( ListPartsInfo , error ) {
// Verify if bucket is valid.
if ! IsValidBucketName ( bucket ) {
return ListPartsInfo { } , BucketNameInvalid { Bucket : bucket }
return ListPartsInfo { } , traceError ( BucketNameInvalid { Bucket : bucket } )
}
// Verify whether the bucket exists.
if ! fs . isBucketExist ( bucket ) {
return ListPartsInfo { } , BucketNotFound { Bucket : bucket }
return ListPartsInfo { } , traceError ( BucketNotFound { Bucket : bucket } )
}
if ! IsValidObjectName ( object ) {
return ListPartsInfo { } , ObjectNameInvalid { Bucket : bucket , Object : object }
return ListPartsInfo { } , traceError ( ObjectNameInvalid { Bucket : bucket , Object : object } )
}
// generates random string on setting MINIO_DEBUG=lock, else returns empty string.
@ -598,7 +598,7 @@ func (fs fsObjects) ListObjectParts(bucket, object, uploadID string, partNumberM
defer nsMutex . Unlock ( minioMetaBucket , pathJoin ( mpartMetaPrefix , bucket , object , uploadID ) , opsID )
if ! fs . isUploadIDExists ( bucket , object , uploadID ) {
return ListPartsInfo { } , InvalidUploadID { UploadID : uploadID }
return ListPartsInfo { } , traceError ( InvalidUploadID { UploadID : uploadID } )
}
return fs . listObjectParts ( bucket , object , uploadID , partNumberMarker , maxParts )
}
@ -612,17 +612,17 @@ func (fs fsObjects) ListObjectParts(bucket, object, uploadID string, partNumberM
func ( fs fsObjects ) CompleteMultipartUpload ( bucket string , object string , uploadID string , parts [ ] completePart ) ( string , error ) {
// Verify if bucket is valid.
if ! IsValidBucketName ( bucket ) {
return "" , BucketNameInvalid { Bucket : bucket }
return "" , traceError ( BucketNameInvalid { Bucket : bucket } )
}
// Verify whether the bucket exists.
if ! fs . isBucketExist ( bucket ) {
return "" , BucketNotFound { Bucket : bucket }
return "" , traceError ( BucketNotFound { Bucket : bucket } )
}
if ! IsValidObjectName ( object ) {
return "" , ObjectNameInvalid {
return "" , traceError ( ObjectNameInvalid {
Bucket : bucket ,
Object : object ,
}
} )
}
uploadIDPath := path . Join ( mpartMetaPrefix , bucket , object , uploadID )
@ -638,7 +638,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
defer nsMutex . Unlock ( minioMetaBucket , uploadIDPath , opsID )
if ! fs . isUploadIDExists ( bucket , object , uploadID ) {
return "" , InvalidUploadID { UploadID : uploadID }
return "" , traceError ( InvalidUploadID { UploadID : uploadID } )
}
// fs-append.json path
@ -650,21 +650,21 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
// Calculate s3 compatible md5sum for complete multipart.
s3MD5 , err := completeMultipartMD5 ( parts ... )
if err != nil {
return "" , err
return "" , traceError ( err )
}
// Read saved fs metadata for ongoing multipart.
fsMetaPath := pathJoin ( uploadIDPath , fsMetaJSONFile )
fsMeta , err := readFSMetadata ( fs . storage , minioMetaBucket , fsMetaPath )
if err != nil {
return "" , toObjectErr ( err , minioMetaBucket , fsMetaPath )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , fsMetaPath )
}
fsAppendMeta , err := readFSMetadata ( fs . storage , minioMetaBucket , fsAppendMetaPath )
if err == nil && isPartsSame ( fsAppendMeta . Parts , parts ) {
fsAppendDataPath := getFSAppendDataPath ( uploadID )
if err = fs . storage . RenameFile ( minioMetaBucket , fsAppendDataPath , bucket , object ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , fsAppendDataPath )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , fsAppendDataPath )
}
// Remove the append-file metadata file in tmp location as we no longer need it.
fs . storage . DeleteFile ( minioMetaBucket , fsAppendMetaPath )
@ -678,18 +678,18 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
for i , part := range parts {
partIdx := fsMeta . ObjectPartIndex ( part . PartNumber )
if partIdx == - 1 {
return "" , InvalidPart { }
return "" , traceError ( InvalidPart { } )
}
if fsMeta . Parts [ partIdx ] . ETag != part . ETag {
return "" , BadDigest { }
return "" , traceError ( BadDigest { } )
}
// All parts except the last part has to be atleast 5MB.
if ( i < len ( parts ) - 1 ) && ! isMinAllowedPartSize ( fsMeta . Parts [ partIdx ] . Size ) {
return "" , PartTooSmall {
return "" , traceError ( PartTooSmall {
PartNumber : part . PartNumber ,
PartSize : fsMeta . Parts [ partIdx ] . Size ,
PartETag : part . ETag ,
}
} )
}
// Construct part suffix.
partSuffix := fmt . Sprintf ( "object%d" , part . PartNumber )
@ -705,7 +705,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
n , err = fs . storage . ReadFile ( minioMetaBucket , multipartPartFile , offset , buf [ : curLeft ] )
if n > 0 {
if err = fs . storage . AppendFile ( minioMetaBucket , tempObj , buf [ : n ] ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , tempObj )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , tempObj )
}
}
if err != nil {
@ -713,9 +713,9 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
break
}
if err == errFileNotFound {
return "" , InvalidPart { }
return "" , traceError ( InvalidPart { } )
}
return "" , toObjectErr ( err , minioMetaBucket , multipartPartFile )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , multipartPartFile )
}
offset += n
totalLeft -= n
@ -726,9 +726,9 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
err = fs . storage . RenameFile ( minioMetaBucket , tempObj , bucket , object )
if err != nil {
if dErr := fs . storage . DeleteFile ( minioMetaBucket , tempObj ) ; dErr != nil {
return "" , toObjectErr ( dErr , minioMetaBucket , tempObj )
return "" , toObjectErr ( traceError ( dErr ) , minioMetaBucket , tempObj )
}
return "" , toObjectErr ( err , bucket , object )
return "" , toObjectErr ( traceError ( err ) , bucket , object )
}
}
@ -742,7 +742,8 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
}
fsMeta . Meta [ "md5Sum" ] = s3MD5
fsMetaPath = path . Join ( bucketMetaPrefix , bucket , object , fsMetaJSONFile )
fsMetaPath := path . Join ( bucketMetaPrefix , bucket , object , fsMetaJSONFile )
// Write the metadata to a temp file and rename it to the actual location.
if err = writeFSMetadata ( fs . storage , minioMetaBucket , fsMetaPath , fsMeta ) ; err != nil {
return "" , toObjectErr ( err , bucket , object )
}
@ -750,7 +751,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
// Cleanup all the parts if everything else has been safely committed.
if err = cleanupUploadedParts ( bucket , object , uploadID , fs . storage ) ; err != nil {
return "" , toObjectErr ( err , bucket , object )
return "" , toObjectErr ( traceError ( err ) , bucket , object )
}
// generates random string on setting MINIO_DEBUG=lock, else returns empty string.
@ -766,7 +767,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
// the object, if yes do not attempt to delete 'uploads.json'.
uploadsJSON , err := readUploadsJSON ( bucket , object , fs . storage )
if err != nil {
return "" , toObjectErr ( err , minioMetaBucket , object )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , object )
}
// If we have successfully read `uploads.json`, then we proceed to
// purge or update `uploads.json`.
@ -776,14 +777,14 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
}
if len ( uploadsJSON . Uploads ) > 0 {
if err = fs . updateUploadsJSON ( bucket , object , uploadsJSON ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object ) )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object ) )
}
// Return success.
return s3MD5 , nil
}
if err = fs . storage . DeleteFile ( minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object , uploadsJSONFile ) ) ; err != nil {
return "" , toObjectErr ( err , minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object ) )
return "" , toObjectErr ( traceError ( err ) , minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object ) )
}
// Return md5sum.
@ -820,7 +821,7 @@ func (fs fsObjects) abortMultipartUpload(bucket, object, uploadID string) error
} // No more pending uploads for the object, we purge the entire
// entry at '.minio/multipart/bucket/object'.
if err = fs . storage . DeleteFile ( minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object , uploadsJSONFile ) ) ; err != nil {
return toObjectErr ( err , minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object ) )
return toObjectErr ( traceError ( err ) , minioMetaBucket , path . Join ( mpartMetaPrefix , bucket , object ) )
}
return nil
}
@ -840,13 +841,13 @@ func (fs fsObjects) abortMultipartUpload(bucket, object, uploadID string) error
func ( fs fsObjects ) AbortMultipartUpload ( bucket , object , uploadID string ) error {
// Verify if bucket is valid.
if ! IsValidBucketName ( bucket ) {
return BucketNameInvalid { Bucket : bucket }
return traceError ( BucketNameInvalid { Bucket : bucket } )
}
if ! fs . isBucketExist ( bucket ) {
return BucketNotFound { Bucket : bucket }
return traceError ( BucketNotFound { Bucket : bucket } )
}
if ! IsValidObjectName ( object ) {
return ObjectNameInvalid { Bucket : bucket , Object : object }
return traceError ( ObjectNameInvalid { Bucket : bucket , Object : object } )
}
// generates random string on setting MINIO_DEBUG=lock, else returns empty string.
@ -858,7 +859,7 @@ func (fs fsObjects) AbortMultipartUpload(bucket, object, uploadID string) error
defer nsMutex . Unlock ( minioMetaBucket , pathJoin ( mpartMetaPrefix , bucket , object , uploadID ) , opsID )
if ! fs . isUploadIDExists ( bucket , object , uploadID ) {
return InvalidUploadID { UploadID : uploadID }
return traceError ( InvalidUploadID { UploadID : uploadID } )
}
fsAppendMetaPath := getFSAppendMetaPath ( uploadID )