|
|
@ -34,6 +34,14 @@ func (xl xlObjects) getUploadIDDir(bucket, object, uploadID string) string { |
|
|
|
return pathJoin(xl.getMultipartSHADir(bucket, object), uploadID) |
|
|
|
return pathJoin(xl.getMultipartSHADir(bucket, object), uploadID) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// getUploadIDLockPath returns the name of the Lock in the form of
|
|
|
|
|
|
|
|
// bucket/object/uploadID. For locking, the path bucket/object/uploadID
|
|
|
|
|
|
|
|
// is locked instead of multipart-sha256-Dir/uploadID as it is more
|
|
|
|
|
|
|
|
// readable in the list-locks output which helps in debugging.
|
|
|
|
|
|
|
|
func (xl xlObjects) getUploadIDLockPath(bucket, object, uploadID string) string { |
|
|
|
|
|
|
|
return pathJoin(bucket, object, uploadID) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (xl xlObjects) getMultipartSHADir(bucket, object string) string { |
|
|
|
func (xl xlObjects) getMultipartSHADir(bucket, object string) string { |
|
|
|
return getSHA256Hash([]byte(pathJoin(bucket, object))) |
|
|
|
return getSHA256Hash([]byte(pathJoin(bucket, object))) |
|
|
|
} |
|
|
|
} |
|
|
@ -290,9 +298,10 @@ func (xl xlObjects) PutObjectPart(ctx context.Context, bucket, object, uploadID |
|
|
|
var partsMetadata []xlMetaV1 |
|
|
|
var partsMetadata []xlMetaV1 |
|
|
|
var errs []error |
|
|
|
var errs []error |
|
|
|
uploadIDPath := xl.getUploadIDDir(bucket, object, uploadID) |
|
|
|
uploadIDPath := xl.getUploadIDDir(bucket, object, uploadID) |
|
|
|
|
|
|
|
uploadIDLockPath := xl.getUploadIDLockPath(bucket, object, uploadID) |
|
|
|
|
|
|
|
|
|
|
|
// pre-check upload id lock.
|
|
|
|
// pre-check upload id lock.
|
|
|
|
preUploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath) |
|
|
|
preUploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDLockPath) |
|
|
|
if err := preUploadIDLock.GetRLock(globalOperationTimeout); err != nil { |
|
|
|
if err := preUploadIDLock.GetRLock(globalOperationTimeout); err != nil { |
|
|
|
return pi, err |
|
|
|
return pi, err |
|
|
|
} |
|
|
|
} |
|
|
@ -398,7 +407,7 @@ func (xl xlObjects) PutObjectPart(ctx context.Context, bucket, object, uploadID |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// post-upload check (write) lock
|
|
|
|
// post-upload check (write) lock
|
|
|
|
postUploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath) |
|
|
|
postUploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDLockPath) |
|
|
|
if err = postUploadIDLock.GetLock(globalOperationTimeout); err != nil { |
|
|
|
if err = postUploadIDLock.GetLock(globalOperationTimeout); err != nil { |
|
|
|
return pi, err |
|
|
|
return pi, err |
|
|
|
} |
|
|
|
} |
|
|
@ -491,7 +500,7 @@ func (xl xlObjects) ListObjectParts(ctx context.Context, bucket, object, uploadI |
|
|
|
// Hold lock so that there is no competing
|
|
|
|
// Hold lock so that there is no competing
|
|
|
|
// abort-multipart-upload or complete-multipart-upload.
|
|
|
|
// abort-multipart-upload or complete-multipart-upload.
|
|
|
|
uploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, |
|
|
|
uploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, |
|
|
|
xl.getUploadIDDir(bucket, object, uploadID)) |
|
|
|
xl.getUploadIDLockPath(bucket, object, uploadID)) |
|
|
|
if err := uploadIDLock.GetLock(globalListingTimeout); err != nil { |
|
|
|
if err := uploadIDLock.GetLock(globalListingTimeout); err != nil { |
|
|
|
return result, err |
|
|
|
return result, err |
|
|
|
} |
|
|
|
} |
|
|
@ -579,6 +588,7 @@ func (xl xlObjects) CompleteMultipartUpload(ctx context.Context, bucket string, |
|
|
|
defer destLock.Unlock() |
|
|
|
defer destLock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
uploadIDPath := xl.getUploadIDDir(bucket, object, uploadID) |
|
|
|
uploadIDPath := xl.getUploadIDDir(bucket, object, uploadID) |
|
|
|
|
|
|
|
uploadIDLockPath := xl.getUploadIDLockPath(bucket, object, uploadID) |
|
|
|
|
|
|
|
|
|
|
|
// Hold lock so that
|
|
|
|
// Hold lock so that
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -586,7 +596,7 @@ func (xl xlObjects) CompleteMultipartUpload(ctx context.Context, bucket string, |
|
|
|
//
|
|
|
|
//
|
|
|
|
// 2) no one does a parallel complete-multipart-upload on this
|
|
|
|
// 2) no one does a parallel complete-multipart-upload on this
|
|
|
|
// multipart upload
|
|
|
|
// multipart upload
|
|
|
|
uploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath) |
|
|
|
uploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDLockPath) |
|
|
|
if err := uploadIDLock.GetLock(globalOperationTimeout); err != nil { |
|
|
|
if err := uploadIDLock.GetLock(globalOperationTimeout); err != nil { |
|
|
|
return oi, err |
|
|
|
return oi, err |
|
|
|
} |
|
|
|
} |
|
|
@ -785,9 +795,10 @@ func (xl xlObjects) AbortMultipartUpload(ctx context.Context, bucket, object, up |
|
|
|
} |
|
|
|
} |
|
|
|
// Construct uploadIDPath.
|
|
|
|
// Construct uploadIDPath.
|
|
|
|
uploadIDPath := xl.getUploadIDDir(bucket, object, uploadID) |
|
|
|
uploadIDPath := xl.getUploadIDDir(bucket, object, uploadID) |
|
|
|
|
|
|
|
uploadIDLockPath := xl.getUploadIDLockPath(bucket, object, uploadID) |
|
|
|
// Hold lock so that there is no competing
|
|
|
|
// Hold lock so that there is no competing
|
|
|
|
// complete-multipart-upload or put-object-part.
|
|
|
|
// complete-multipart-upload or put-object-part.
|
|
|
|
uploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath) |
|
|
|
uploadIDLock := xl.nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDLockPath) |
|
|
|
if err := uploadIDLock.GetLock(globalOperationTimeout); err != nil { |
|
|
|
if err := uploadIDLock.GetLock(globalOperationTimeout); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|