From e3b4910b6677a0d0c2dd6327f68986959aae6d0c Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Wed, 30 Nov 2016 12:56:36 +0530 Subject: [PATCH] FS/CompleteMultipart: lock the namespace before renaming the appended tmp file. (#3371) --- cmd/fs-v1-multipart.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index 359ce87b2..255f354ac 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -574,11 +574,16 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload return "", toObjectErr(err, minioMetaMultipartBucket, fsMetaPath) } + // This lock is held during rename of the appended tmp file to the actual + // location so that any competing GetObject/PutObject/DeleteObject do not race. + objectLock := nsMutex.NewNSLock(bucket, object) appendFallback := true // In case background-append did not append the required parts. if isPartsSame(fsMeta.Parts, parts) { err = fs.bgAppend.complete(fs.storage, bucket, object, uploadID, fsMeta) if err == nil { appendFallback = false + objectLock.Lock() + defer objectLock.Unlock() if err = fs.storage.RenameFile(minioMetaTmpBucket, uploadID, bucket, object); err != nil { return "", toObjectErr(traceError(err), minioMetaTmpBucket, uploadID) } @@ -653,6 +658,8 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload } } + objectLock.Lock() + defer objectLock.Unlock() // Rename the file back to original location, if not delete the temporary object. err = fs.storage.RenameFile(minioMetaTmpBucket, tempObj, bucket, object) if err != nil {