@ -65,64 +65,61 @@ func (xl xlObjects) putObjectDir(ctx context.Context, bucket, object string, wri
// if source object and destination object are same we only
// if source object and destination object are same we only
// update metadata.
// update metadata.
func ( xl xlObjects ) CopyObject ( ctx context . Context , srcBucket , srcObject , dstBucket , dstObject string , srcInfo ObjectInfo , srcOpts , dstOpts ObjectOptions ) ( oi ObjectInfo , e error ) {
func ( xl xlObjects ) CopyObject ( ctx context . Context , srcBucket , srcObject , dstBucket , dstObject string , srcInfo ObjectInfo , srcOpts , dstOpts ObjectOptions ) ( oi ObjectInfo , e error ) {
cpSrcDstSame := isStringEqual ( pathJoin ( srcBucket , srcObject ) , pathJoin ( dstBucket , dstObject ) )
// This call shouldn't be used for anything other than metadata updates.
if ! srcInfo . metadataOnly {
// Check if this request is only metadata update.
return oi , NotImplemented { }
if cpSrcDstSame {
}
defer ObjectPathUpdated ( path . Join ( dstBucket , dstObject ) )
// Read metadata associated with the object from all disks.
defer ObjectPathUpdated ( path . Join ( dstBucket , dstObject ) )
storageDisks := xl . getDisks ( )
metaArr , errs := readAllXLMetadata ( ctx , storageDisks , srcBucket , srcObject )
// Read metadata associated with the object from all disks.
storageDisks := xl . getDisks ( )
// get Quorum for this object
metaArr , errs := readAllXLMetadata ( ctx , storageDisks , srcBucket , srcObject )
readQuorum , writeQuorum , err := objectQuorumFromMeta ( ctx , xl , metaArr , errs )
if err != nil {
return oi , toObjectErr ( err , srcBucket , srcObject )
}
if reducedErr := reduceReadQuorumErrs ( ctx , errs , objectOpIgnoredErrs , readQuorum ) ; reducedErr != nil {
// get Quorum for this object
return oi , toObjectErr ( reducedErr , srcBucket , srcObject )
readQuorum , writeQuorum , err := objectQuorumFromMeta ( ctx , xl , metaArr , errs )
}
if err != nil {
return oi , toObjectErr ( err , srcBucket , srcObject )
}
// List all online disks.
if reducedErr := reduceReadQuorumErrs ( ctx , errs , objectOpIgnoredErrs , readQuorum ) ; reducedErr != nil {
_ , modTime := listOnlineDisks ( storageDisks , metaArr , errs )
return oi , toObjectErr ( reducedErr , srcBucket , srcObject )
}
// Pick latest valid metadata.
// List all online disks.
xlMeta , err := pickValidXLMeta ( ctx , metaArr , modTime , readQuorum )
_ , modTime := listOnlineDisks ( storageDisks , metaArr , errs )
if err != nil {
return oi , toObjectErr ( err , srcBucket , srcObject )
}
// Update `xl.json` content on each disks .
// Pick latest valid metadata.
for index := range metaArr {
xlMeta , err := pickValidXLMeta ( ctx , metaArr , modTime , readQuorum )
metaArr [ index ] . Meta = srcInfo . UserDefined
if err != nil {
metaArr [ index ] . Meta [ "etag" ] = srcInfo . ETag
return oi , toObjectErr ( err , srcBucket , srcObject )
}
}
var onlineDisks [ ] StorageAPI
// Update `xl.json` content on each disks.
for index := range metaArr {
metaArr [ index ] . Meta = srcInfo . UserDefined
metaArr [ index ] . Meta [ "etag" ] = srcInfo . ETag
}
tempObj := mustGetUUID ( )
var onlineDisks [ ] StorageAPI
// Cleanup in case of xl.json writing failure
tempObj := mustGetUUID ( )
defer xl . deleteObject ( ctx , minioMetaTmpBucket , tempObj , writeQuorum , false )
// Write unique `xl.json` for each disk.
// Cleanup in case of xl.json writing failure
if onlineDisks , err = writeUniqueXLMetadata ( ctx , storageDisks , minioMetaTmpBucket , tempObj , metaArr , writeQuorum ) ; err != nil {
defer xl . deleteObject ( ctx , minioMetaTmpBucket , tempObj , writeQuorum , false )
return oi , toObjectErr ( err , srcBucket , srcObject )
}
// Rename atomically `xl.json` from tmp location to destination for each disk.
// Write unique `xl.json` for each disk.
if _ , err = renam eXLMetadata( ctx , onlin eDisks, minioMetaTmpBucket , tempObj , srcBucket , srcObject , writeQuorum ) ; err != nil {
if onlineDisks , err = writeUniqu eXLMetadata( ctx , storag eDisks, minioMetaTmpBucket , tempObj , metaArr , writeQuorum ) ; err != nil {
return oi , toObjectErr ( err , srcBucket , srcObject )
return oi , toObjectErr ( err , srcBucket , srcObject )
}
}
return xlMeta . ToObjectInfo ( srcBucket , srcObject ) , nil
// Rename atomically `xl.json` from tmp location to destination for each disk.
if _ , err = renameXLMetadata ( ctx , onlineDisks , minioMetaTmpBucket , tempObj , srcBucket , srcObject , writeQuorum ) ; err != nil {
return oi , toObjectErr ( err , srcBucket , srcObject )
}
}
putOpts := ObjectOptions { ServerSideEncryption : dstOpts . ServerSideEncryption , UserDefined : srcInfo . UserDefined }
return xlMeta . ToObjectInfo ( srcBucket , srcObject ) , nil
return xl . PutObject ( ctx , dstBucket , dstObject , srcInfo . PutObjReader , putOpts )
}
}
// GetObjectNInfo - returns object info and an object
// GetObjectNInfo - returns object info and an object