mirror of
https://github.com/minio/minio.git
synced 2025-04-16 08:58:11 -04:00
avoid partID lock validating uploadID exists prematurely (#16086)
This commit is contained in:
parent
7198be5be9
commit
6aea950d74
@ -567,16 +567,6 @@ func writeAllDisks(ctx context.Context, disks []StorageAPI, dstBucket, dstEntry
|
|||||||
func (er erasureObjects) PutObjectPart(ctx context.Context, bucket, object, uploadID string, partID int, r *PutObjReader, opts ObjectOptions) (pi PartInfo, err error) {
|
func (er erasureObjects) PutObjectPart(ctx context.Context, bucket, object, uploadID string, partID int, r *PutObjReader, opts ObjectOptions) (pi PartInfo, err error) {
|
||||||
auditObjectErasureSet(ctx, object, &er)
|
auditObjectErasureSet(ctx, object, &er)
|
||||||
|
|
||||||
// Write lock for this part ID.
|
|
||||||
// Held throughout the operation.
|
|
||||||
partIDLock := er.NewNSLock(bucket, pathJoin(object, uploadID, strconv.Itoa(partID)))
|
|
||||||
plkctx, err := partIDLock.GetLock(ctx, globalOperationTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return PartInfo{}, err
|
|
||||||
}
|
|
||||||
pctx := plkctx.Context()
|
|
||||||
defer partIDLock.Unlock(plkctx.Cancel)
|
|
||||||
|
|
||||||
// Read lock for upload id.
|
// Read lock for upload id.
|
||||||
// Only held while reading the upload metadata.
|
// Only held while reading the upload metadata.
|
||||||
uploadIDRLock := er.NewNSLock(bucket, pathJoin(object, uploadID))
|
uploadIDRLock := er.NewNSLock(bucket, pathJoin(object, uploadID))
|
||||||
@ -587,6 +577,13 @@ func (er erasureObjects) PutObjectPart(ctx context.Context, bucket, object, uplo
|
|||||||
rctx := rlkctx.Context()
|
rctx := rlkctx.Context()
|
||||||
defer uploadIDRLock.RUnlock(rlkctx.Cancel)
|
defer uploadIDRLock.RUnlock(rlkctx.Cancel)
|
||||||
|
|
||||||
|
uploadIDPath := er.getUploadIDDir(bucket, object, uploadID)
|
||||||
|
// Validates if upload ID exists.
|
||||||
|
fi, _, err := er.checkUploadIDExists(rctx, bucket, object, uploadID, true)
|
||||||
|
if err != nil {
|
||||||
|
return pi, toObjectErr(err, bucket, object, uploadID)
|
||||||
|
}
|
||||||
|
|
||||||
data := r.Reader
|
data := r.Reader
|
||||||
// Validate input data size and it can never be less than zero.
|
// Validate input data size and it can never be less than zero.
|
||||||
if data.Size() < -1 {
|
if data.Size() < -1 {
|
||||||
@ -594,13 +591,17 @@ func (er erasureObjects) PutObjectPart(ctx context.Context, bucket, object, uplo
|
|||||||
return pi, toObjectErr(errInvalidArgument)
|
return pi, toObjectErr(errInvalidArgument)
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadIDPath := er.getUploadIDDir(bucket, object, uploadID)
|
// Write lock for this part ID, only hold it if we are planning to read from the
|
||||||
|
// streamto avoid any concurrent updates.
|
||||||
// Validates if upload ID exists.
|
//
|
||||||
fi, _, err := er.checkUploadIDExists(rctx, bucket, object, uploadID, true)
|
// Must be held throughout this call.
|
||||||
|
partIDLock := er.NewNSLock(bucket, pathJoin(object, uploadID, strconv.Itoa(partID)))
|
||||||
|
plkctx, err := partIDLock.GetLock(ctx, globalOperationTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pi, toObjectErr(err, bucket, object, uploadID)
|
return PartInfo{}, err
|
||||||
}
|
}
|
||||||
|
pctx := plkctx.Context()
|
||||||
|
defer partIDLock.Unlock(plkctx.Cancel)
|
||||||
|
|
||||||
onlineDisks := er.getDisks()
|
onlineDisks := er.getDisks()
|
||||||
writeQuorum := fi.WriteQuorum(er.defaultWQuorum())
|
writeQuorum := fi.WriteQuorum(er.defaultWQuorum())
|
||||||
|
@ -1076,9 +1076,12 @@ func (z *erasureServerPools) DeleteObjects(ctx context.Context, bucket string, o
|
|||||||
NoLock: true,
|
NoLock: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
derrs[j] = err
|
if !isErrObjectNotFound(err) && !isErrVersionNotFound(err) {
|
||||||
|
derrs[j] = err
|
||||||
|
}
|
||||||
dobjects[j] = DeletedObject{
|
dobjects[j] = DeletedObject{
|
||||||
ObjectName: obj.ObjectName,
|
ObjectName: obj.ObjectName,
|
||||||
|
VersionID: obj.VersionID,
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1435,9 +1438,9 @@ func (z *erasureServerPools) PutObjectPart(ctx context.Context, bucket, object,
|
|||||||
if z.IsSuspended(idx) {
|
if z.IsSuspended(idx) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err := pool.GetMultipartInfo(ctx, bucket, object, uploadID, opts)
|
pi, err := pool.PutObjectPart(ctx, bucket, object, uploadID, partID, data, opts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return pool.PutObjectPart(ctx, bucket, object, uploadID, partID, data, opts)
|
return pi, nil
|
||||||
}
|
}
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case InvalidUploadID:
|
case InvalidUploadID:
|
||||||
@ -1499,9 +1502,9 @@ func (z *erasureServerPools) ListObjectParts(ctx context.Context, bucket, object
|
|||||||
if z.IsSuspended(idx) {
|
if z.IsSuspended(idx) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err := pool.GetMultipartInfo(ctx, bucket, object, uploadID, opts)
|
result, err := pool.ListObjectParts(ctx, bucket, object, uploadID, partNumberMarker, maxParts, opts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return pool.ListObjectParts(ctx, bucket, object, uploadID, partNumberMarker, maxParts, opts)
|
return result, nil
|
||||||
}
|
}
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case InvalidUploadID:
|
case InvalidUploadID:
|
||||||
@ -1530,9 +1533,9 @@ func (z *erasureServerPools) AbortMultipartUpload(ctx context.Context, bucket, o
|
|||||||
if z.IsSuspended(idx) {
|
if z.IsSuspended(idx) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err := pool.GetMultipartInfo(ctx, bucket, object, uploadID, opts)
|
err := pool.AbortMultipartUpload(ctx, bucket, object, uploadID, opts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return pool.AbortMultipartUpload(ctx, bucket, object, uploadID, opts)
|
return nil
|
||||||
}
|
}
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case InvalidUploadID:
|
case InvalidUploadID:
|
||||||
@ -1562,10 +1565,16 @@ func (z *erasureServerPools) CompleteMultipartUpload(ctx context.Context, bucket
|
|||||||
if z.IsSuspended(idx) {
|
if z.IsSuspended(idx) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err := pool.GetMultipartInfo(ctx, bucket, object, uploadID, opts)
|
objInfo, err = pool.CompleteMultipartUpload(ctx, bucket, object, uploadID, uploadedParts, opts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return pool.CompleteMultipartUpload(ctx, bucket, object, uploadID, uploadedParts, opts)
|
return objInfo, nil
|
||||||
}
|
}
|
||||||
|
switch err.(type) {
|
||||||
|
case InvalidUploadID:
|
||||||
|
// upload id not found move to next pool
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return objInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return objInfo, InvalidUploadID{
|
return objInfo, InvalidUploadID{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user