From c83055500df9f4624c985fe43ea31f8be68d0644 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Fri, 7 Jul 2017 08:41:29 -0700 Subject: [PATCH] fs: Fail CompleteMultipartUpload if partSize < 5M unless it is last part (#4642) fixes #4625 --- cmd/fs-v1-multipart.go | 48 ++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index f3c7bc246..84ab60c97 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -757,6 +757,30 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload return oi, toObjectErr(err, minioMetaMultipartBucket, fsMetaPathMultipart) } + // Validate all parts and then commit to disk. + for i, part := range parts { + partIdx := fsMeta.ObjectPartIndex(part.PartNumber) + if partIdx == -1 { + fs.rwPool.Close(fsMetaPathMultipart) + return oi, traceError(InvalidPart{}) + } + + if fsMeta.Parts[partIdx].ETag != part.ETag { + fs.rwPool.Close(fsMetaPathMultipart) + return oi, traceError(InvalidPart{}) + } + + // All parts except the last part has to be atleast 5MB. + if (i < len(parts)-1) && !isMinAllowedPartSize(fsMeta.Parts[partIdx].Size) { + fs.rwPool.Close(fsMetaPathMultipart) + return oi, traceError(PartTooSmall{ + PartNumber: part.PartNumber, + PartSize: fsMeta.Parts[partIdx].Size, + PartETag: part.ETag, + }) + } + } + // Wait for any competing PutObject() operation on bucket/object, since same namespace // would be acquired for `fs.json`. fsMetaPath := pathJoin(fs.fsPath, minioMetaBucket, bucketMetaPrefix, bucket, object, fsMetaJSONFile) @@ -798,29 +822,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload // Allocate staging buffer. var buf = make([]byte, readSizeV1) - // Validate all parts and then commit to disk. - for i, part := range parts { - partIdx := fsMeta.ObjectPartIndex(part.PartNumber) - if partIdx == -1 { - fs.rwPool.Close(fsMetaPathMultipart) - return oi, traceError(InvalidPart{}) - } - - if fsMeta.Parts[partIdx].ETag != part.ETag { - fs.rwPool.Close(fsMetaPathMultipart) - return oi, traceError(InvalidPart{}) - } - - // All parts except the last part has to be atleast 5MB. - if (i < len(parts)-1) && !isMinAllowedPartSize(fsMeta.Parts[partIdx].Size) { - fs.rwPool.Close(fsMetaPathMultipart) - return oi, traceError(PartTooSmall{ - PartNumber: part.PartNumber, - PartSize: fsMeta.Parts[partIdx].Size, - PartETag: part.ETag, - }) - } - + for _, part := range parts { // Construct part suffix. partSuffix := fmt.Sprintf("object%d", part.PartNumber) multipartPartFile := pathJoin(fs.fsPath, minioMetaMultipartBucket, uploadIDPath, partSuffix)