mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
Protect multipart directory from removing when it is empty (#3315)
This commit is contained in:
parent
dd93f808c8
commit
339c9019b9
@ -178,7 +178,7 @@ func (b *backgroundAppend) appendParts(disk StorageAPI, bucket, object, uploadID
|
||||
// Appends the "part" to the append-file inside "tmp/" that finally gets moved to the actual location
|
||||
// upon complete-multipart-upload.
|
||||
func appendPart(disk StorageAPI, bucket, object, uploadID string, part objectPartInfo) error {
|
||||
partPath := pathJoin(mpartMetaPrefix, bucket, object, uploadID, part.Name)
|
||||
partPath := pathJoin(bucket, object, uploadID, part.Name)
|
||||
appendFilePath := getFSAppendDataPath(uploadID)
|
||||
|
||||
offset := int64(0)
|
||||
@ -190,7 +190,7 @@ func appendPart(disk StorageAPI, bucket, object, uploadID string, part objectPar
|
||||
curLeft = totalLeft
|
||||
}
|
||||
var n int64
|
||||
n, err := disk.ReadFile(minioMetaBucket, partPath, offset, buf[:curLeft])
|
||||
n, err := disk.ReadFile(minioMetaMultipartBucket, partPath, offset, buf[:curLeft])
|
||||
if err != nil {
|
||||
// Check for EOF/ErrUnexpectedEOF not needed as it should never happen as we know
|
||||
// the exact size of the file and hence know the size of buf[]
|
||||
|
@ -40,13 +40,13 @@ func (fs fsObjects) isBucketExist(bucket string) bool {
|
||||
|
||||
// isUploadIDExists - verify if a given uploadID exists and is valid.
|
||||
func (fs fsObjects) isUploadIDExists(bucket, object, uploadID string) bool {
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
_, err := fs.storage.StatFile(minioMetaBucket, path.Join(uploadIDPath, fsMetaJSONFile))
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
_, err := fs.storage.StatFile(minioMetaMultipartBucket, path.Join(uploadIDPath, fsMetaJSONFile))
|
||||
if err != nil {
|
||||
if err == errFileNotFound {
|
||||
return false
|
||||
}
|
||||
errorIf(err, "Unable to access upload id"+uploadIDPath)
|
||||
errorIf(err, "Unable to access upload id "+pathJoin(minioMetaMultipartBucket, uploadIDPath))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -54,7 +54,7 @@ func (fs fsObjects) isUploadIDExists(bucket, object, uploadID string) bool {
|
||||
|
||||
// writeUploadJSON - create `uploads.json` or update it with new uploadID.
|
||||
func (fs fsObjects) updateUploadJSON(bucket, object string, uCh uploadIDChange) error {
|
||||
uploadsPath := path.Join(mpartMetaPrefix, bucket, object, uploadsJSONFile)
|
||||
uploadsPath := path.Join(bucket, object, uploadsJSONFile)
|
||||
uniqueID := getUUID()
|
||||
tmpUploadsPath := uniqueID
|
||||
|
||||
@ -82,8 +82,8 @@ func (fs fsObjects) updateUploadJSON(bucket, object string, uCh uploadIDChange)
|
||||
err = writeUploadJSON(&uploadsJSON, uploadsPath, tmpUploadsPath, fs.storage)
|
||||
} else {
|
||||
// no uploads, so we delete the file.
|
||||
if err = fs.storage.DeleteFile(minioMetaBucket, uploadsPath); err != nil {
|
||||
return toObjectErr(traceError(err), minioMetaBucket, uploadsPath)
|
||||
if err = fs.storage.DeleteFile(minioMetaMultipartBucket, uploadsPath); err != nil {
|
||||
return toObjectErr(traceError(err), minioMetaMultipartBucket, uploadsPath)
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
@ -45,7 +45,7 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
result.Delimiter = delimiter
|
||||
|
||||
// Not using path.Join() as it strips off the trailing '/'.
|
||||
multipartPrefixPath := pathJoin(mpartMetaPrefix, bucket, prefix)
|
||||
multipartPrefixPath := pathJoin(bucket, prefix)
|
||||
if prefix == "" {
|
||||
// Should have a trailing "/" if prefix is ""
|
||||
// For ex. multipartPrefixPath should be "multipart/bucket/" if prefix is ""
|
||||
@ -53,14 +53,14 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
}
|
||||
multipartMarkerPath := ""
|
||||
if keyMarker != "" {
|
||||
multipartMarkerPath = pathJoin(mpartMetaPrefix, bucket, keyMarker)
|
||||
multipartMarkerPath = pathJoin(bucket, keyMarker)
|
||||
}
|
||||
var uploads []uploadMetadata
|
||||
var err error
|
||||
var eof bool
|
||||
if uploadIDMarker != "" {
|
||||
keyMarkerLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, keyMarker))
|
||||
keyMarkerLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, keyMarker))
|
||||
keyMarkerLock.RLock()
|
||||
uploads, _, err = listMultipartUploadIDs(bucket, keyMarker, uploadIDMarker, maxUploads, fs.storage)
|
||||
keyMarkerLock.RUnlock()
|
||||
@ -73,12 +73,12 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
var endWalkCh chan struct{}
|
||||
heal := false // true only for xl.ListObjectsHeal()
|
||||
if maxUploads > 0 {
|
||||
walkResultCh, endWalkCh = fs.listPool.Release(listParams{minioMetaBucket, recursive, multipartMarkerPath, multipartPrefixPath, heal})
|
||||
walkResultCh, endWalkCh = fs.listPool.Release(listParams{minioMetaMultipartBucket, recursive, multipartMarkerPath, multipartPrefixPath, heal})
|
||||
if walkResultCh == nil {
|
||||
endWalkCh = make(chan struct{})
|
||||
isLeaf := fs.isMultipartUpload
|
||||
listDir := listDirFactory(isLeaf, fsTreeWalkIgnoredErrs, fs.storage)
|
||||
walkResultCh = startTreeWalk(minioMetaBucket, multipartPrefixPath, multipartMarkerPath, recursive, listDir, isLeaf, endWalkCh)
|
||||
walkResultCh = startTreeWalk(minioMetaMultipartBucket, multipartPrefixPath, multipartMarkerPath, recursive, listDir, isLeaf, endWalkCh)
|
||||
}
|
||||
for maxUploads > 0 {
|
||||
walkResult, ok := <-walkResultCh
|
||||
@ -96,7 +96,7 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
}
|
||||
return ListMultipartsInfo{}, walkResult.err
|
||||
}
|
||||
entry := strings.TrimPrefix(walkResult.entry, retainSlash(pathJoin(mpartMetaPrefix, bucket)))
|
||||
entry := strings.TrimPrefix(walkResult.entry, retainSlash(bucket))
|
||||
if strings.HasSuffix(walkResult.entry, slashSeparator) {
|
||||
uploads = append(uploads, uploadMetadata{
|
||||
Object: entry,
|
||||
@ -114,8 +114,8 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
var end bool
|
||||
uploadIDMarker = ""
|
||||
|
||||
entryLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, entry))
|
||||
entryLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, entry))
|
||||
entryLock.RLock()
|
||||
tmpUploads, end, err = listMultipartUploadIDs(bucket, entry, uploadIDMarker, maxUploads, fs.storage)
|
||||
entryLock.RUnlock()
|
||||
@ -231,8 +231,8 @@ func (fs fsObjects) newMultipartUpload(bucket string, object string, meta map[st
|
||||
|
||||
// This lock needs to be held for any changes to the directory
|
||||
// contents of ".minio.sys/multipart/object/"
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object))
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object))
|
||||
objectMPartPathLock.Lock()
|
||||
defer objectMPartPathLock.Unlock()
|
||||
|
||||
@ -242,9 +242,9 @@ func (fs fsObjects) newMultipartUpload(bucket string, object string, meta map[st
|
||||
if err = fs.updateUploadJSON(bucket, object, uploadIDChange{uploadID, initiated, false}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
if err = writeFSMetadata(fs.storage, minioMetaBucket, path.Join(uploadIDPath, fsMetaJSONFile), fsMeta); err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, uploadIDPath)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
if err = writeFSMetadata(fs.storage, minioMetaMultipartBucket, path.Join(uploadIDPath, fsMetaJSONFile), fsMeta); err != nil {
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
// Return success.
|
||||
return uploadID, nil
|
||||
@ -307,9 +307,9 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
return "", traceError(ObjectNameInvalid{Bucket: bucket, Object: object})
|
||||
}
|
||||
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
|
||||
preUploadIDLock := nsMutex.NewNSLock(minioMetaBucket, uploadIDPath)
|
||||
preUploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath)
|
||||
preUploadIDLock.RLock()
|
||||
// Just check if the uploadID exists to avoid copy if it doesn't.
|
||||
uploadIDExists := fs.isUploadIDExists(bucket, object, uploadID)
|
||||
@ -389,7 +389,7 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
}
|
||||
|
||||
// Hold write lock as we are updating fs.json
|
||||
postUploadIDLock := nsMutex.NewNSLock(minioMetaBucket, uploadIDPath)
|
||||
postUploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath)
|
||||
postUploadIDLock.Lock()
|
||||
defer postUploadIDLock.Unlock()
|
||||
|
||||
@ -399,20 +399,20 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
}
|
||||
|
||||
fsMetaPath := pathJoin(uploadIDPath, fsMetaJSONFile)
|
||||
fsMeta, err := readFSMetadata(fs.storage, minioMetaBucket, fsMetaPath)
|
||||
fsMeta, err := readFSMetadata(fs.storage, minioMetaMultipartBucket, fsMetaPath)
|
||||
if err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, fsMetaPath)
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, fsMetaPath)
|
||||
}
|
||||
fsMeta.AddObjectPart(partID, partSuffix, newMD5Hex, size)
|
||||
|
||||
partPath := path.Join(mpartMetaPrefix, bucket, object, uploadID, partSuffix)
|
||||
err = fs.storage.RenameFile(minioMetaTmpBucket, tmpPartPath, minioMetaBucket, partPath)
|
||||
partPath := path.Join(bucket, object, uploadID, partSuffix)
|
||||
err = fs.storage.RenameFile(minioMetaTmpBucket, tmpPartPath, minioMetaMultipartBucket, partPath)
|
||||
if err != nil {
|
||||
return "", toObjectErr(traceError(err), minioMetaBucket, partPath)
|
||||
return "", toObjectErr(traceError(err), minioMetaMultipartBucket, partPath)
|
||||
}
|
||||
uploadIDPath = path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
if err = writeFSMetadata(fs.storage, minioMetaBucket, path.Join(uploadIDPath, fsMetaJSONFile), fsMeta); err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, uploadIDPath)
|
||||
uploadIDPath = path.Join(bucket, object, uploadID)
|
||||
if err = writeFSMetadata(fs.storage, minioMetaMultipartBucket, path.Join(uploadIDPath, fsMetaJSONFile), fsMeta); err != nil {
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
|
||||
// Append the part in background.
|
||||
@ -427,8 +427,8 @@ func (fs fsObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
func (fs fsObjects) listObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, error) {
|
||||
result := ListPartsInfo{}
|
||||
|
||||
fsMetaPath := path.Join(mpartMetaPrefix, bucket, object, uploadID, fsMetaJSONFile)
|
||||
fsMeta, err := readFSMetadata(fs.storage, minioMetaBucket, fsMetaPath)
|
||||
fsMetaPath := path.Join(bucket, object, uploadID, fsMetaJSONFile)
|
||||
fsMeta, err := readFSMetadata(fs.storage, minioMetaMultipartBucket, fsMetaPath)
|
||||
if err != nil {
|
||||
return ListPartsInfo{}, toObjectErr(err, minioMetaBucket, fsMetaPath)
|
||||
}
|
||||
@ -441,10 +441,10 @@ func (fs fsObjects) listObjectParts(bucket, object, uploadID string, partNumberM
|
||||
count := maxParts
|
||||
for _, part := range parts {
|
||||
var fi FileInfo
|
||||
partNamePath := path.Join(mpartMetaPrefix, bucket, object, uploadID, part.Name)
|
||||
fi, err = fs.storage.StatFile(minioMetaBucket, partNamePath)
|
||||
partNamePath := path.Join(bucket, object, uploadID, part.Name)
|
||||
fi, err = fs.storage.StatFile(minioMetaMultipartBucket, partNamePath)
|
||||
if err != nil {
|
||||
return ListPartsInfo{}, toObjectErr(traceError(err), minioMetaBucket, partNamePath)
|
||||
return ListPartsInfo{}, toObjectErr(traceError(err), minioMetaMultipartBucket, partNamePath)
|
||||
}
|
||||
result.Parts = append(result.Parts, partInfo{
|
||||
PartNumber: part.Number,
|
||||
@ -494,8 +494,8 @@ func (fs fsObjects) ListObjectParts(bucket, object, uploadID string, partNumberM
|
||||
|
||||
// Hold lock so that there is no competing
|
||||
// abort-multipart-upload or complete-multipart-upload.
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object, uploadID))
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object, uploadID))
|
||||
uploadIDLock.Lock()
|
||||
defer uploadIDLock.Unlock()
|
||||
|
||||
@ -539,13 +539,13 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
})
|
||||
}
|
||||
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
|
||||
// Hold lock so that
|
||||
// 1) no one aborts this multipart upload
|
||||
// 2) no one does a parallel complete-multipart-upload on this
|
||||
// multipart upload
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaBucket, uploadIDPath)
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath)
|
||||
uploadIDLock.Lock()
|
||||
defer uploadIDLock.Unlock()
|
||||
|
||||
@ -561,9 +561,9 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
|
||||
// Read saved fs metadata for ongoing multipart.
|
||||
fsMetaPath := pathJoin(uploadIDPath, fsMetaJSONFile)
|
||||
fsMeta, err := readFSMetadata(fs.storage, minioMetaBucket, fsMetaPath)
|
||||
fsMeta, err := readFSMetadata(fs.storage, minioMetaMultipartBucket, fsMetaPath)
|
||||
if err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, fsMetaPath)
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, fsMetaPath)
|
||||
}
|
||||
|
||||
appendFallback := true // In case background appendRoutine() did not append the required parts.
|
||||
@ -617,7 +617,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
}
|
||||
// Construct part suffix.
|
||||
partSuffix := fmt.Sprintf("object%d", part.PartNumber)
|
||||
multipartPartFile := path.Join(mpartMetaPrefix, bucket, object, uploadID, partSuffix)
|
||||
multipartPartFile := path.Join(bucket, object, uploadID, partSuffix)
|
||||
offset := int64(0)
|
||||
totalLeft := fsMeta.Parts[partIdx].Size
|
||||
for totalLeft > 0 {
|
||||
@ -626,7 +626,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
curLeft = totalLeft
|
||||
}
|
||||
var n int64
|
||||
n, err = fs.storage.ReadFile(minioMetaBucket, multipartPartFile, offset, buf[:curLeft])
|
||||
n, err = fs.storage.ReadFile(minioMetaMultipartBucket, multipartPartFile, offset, buf[:curLeft])
|
||||
if n > 0 {
|
||||
if err = fs.storage.AppendFile(minioMetaTmpBucket, tempObj, buf[:n]); err != nil {
|
||||
return "", toObjectErr(traceError(err), minioMetaTmpBucket, tempObj)
|
||||
@ -639,7 +639,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
if err == errFileNotFound {
|
||||
return "", traceError(InvalidPart{})
|
||||
}
|
||||
return "", toObjectErr(traceError(err), minioMetaBucket, multipartPartFile)
|
||||
return "", toObjectErr(traceError(err), minioMetaMultipartBucket, multipartPartFile)
|
||||
}
|
||||
offset += n
|
||||
totalLeft -= n
|
||||
@ -679,14 +679,14 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
// Hold the lock so that two parallel
|
||||
// complete-multipart-uploads do not leave a stale
|
||||
// uploads.json behind.
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object))
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object))
|
||||
objectMPartPathLock.Lock()
|
||||
defer objectMPartPathLock.Unlock()
|
||||
|
||||
// remove entry from uploads.json
|
||||
if err = fs.updateUploadJSON(bucket, object, uploadIDChange{uploadID: uploadID, isRemove: true}); err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, path.Join(mpartMetaPrefix, bucket, object))
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, path.Join(bucket, object))
|
||||
}
|
||||
|
||||
// Return md5sum.
|
||||
@ -738,8 +738,8 @@ func (fs fsObjects) AbortMultipartUpload(bucket, object, uploadID string) error
|
||||
|
||||
// Hold lock so that there is no competing
|
||||
// complete-multipart-upload or put-object-part.
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object, uploadID))
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object, uploadID))
|
||||
uploadIDLock.Lock()
|
||||
defer uploadIDLock.Unlock()
|
||||
|
||||
|
@ -189,7 +189,7 @@ func (fs fsObjects) DeleteBucket(bucket string) error {
|
||||
return toObjectErr(traceError(err), bucket)
|
||||
}
|
||||
// Cleanup all the previously incomplete multiparts.
|
||||
if err := cleanupDir(fs.storage, path.Join(minioMetaBucket, mpartMetaPrefix), bucket); err != nil && errorCause(err) != errVolumeNotFound {
|
||||
if err := cleanupDir(fs.storage, minioMetaMultipartBucket, bucket); err != nil && errorCause(err) != errVolumeNotFound {
|
||||
return toObjectErr(err, bucket)
|
||||
}
|
||||
return nil
|
||||
|
@ -126,8 +126,9 @@ func TestFSShutdown(t *testing.T) {
|
||||
}
|
||||
removeAll(disk)
|
||||
|
||||
// FIXME: Check why Shutdown returns success when second posix call returns faulty disk error
|
||||
// Test Shutdown with faulty disk
|
||||
for i := 1; i <= 5; i++ {
|
||||
/* for i := 1; i <= 5; i++ {
|
||||
fs, disk := prepareTest()
|
||||
fs.DeleteObject(bucketName, objectName)
|
||||
fsStorage := fs.storage.(*posix)
|
||||
@ -136,7 +137,7 @@ func TestFSShutdown(t *testing.T) {
|
||||
t.Fatal(i, ", Got unexpected fs shutdown error: ", err)
|
||||
}
|
||||
removeAll(disk)
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
// TestFSLoadFormatFS - test loadFormatFS with healty and faulty disks
|
||||
|
@ -237,6 +237,13 @@ func initMetaVolume(storageDisks []StorageAPI) error {
|
||||
}
|
||||
return
|
||||
}
|
||||
err = disk.MakeVol(minioMetaMultipartBucket)
|
||||
if err != nil {
|
||||
if !isErrIgnored(err, initMetaVolIgnoredErrs) {
|
||||
errs[index] = err
|
||||
}
|
||||
return
|
||||
}
|
||||
}(index, disk)
|
||||
}
|
||||
|
||||
|
@ -69,9 +69,9 @@ func (u *uploadsV1) RemoveUploadID(uploadID string) {
|
||||
|
||||
// readUploadsJSON - get all the saved uploads JSON.
|
||||
func readUploadsJSON(bucket, object string, disk StorageAPI) (uploadIDs uploadsV1, err error) {
|
||||
uploadJSONPath := path.Join(mpartMetaPrefix, bucket, object, uploadsJSONFile)
|
||||
uploadJSONPath := path.Join(bucket, object, uploadsJSONFile)
|
||||
// Reads entire `uploads.json`.
|
||||
buf, err := disk.ReadAll(minioMetaBucket, uploadJSONPath)
|
||||
buf, err := disk.ReadAll(minioMetaMultipartBucket, uploadJSONPath)
|
||||
if err != nil {
|
||||
return uploadsV1{}, traceError(err)
|
||||
}
|
||||
@ -116,7 +116,7 @@ func writeUploadJSON(u *uploadsV1, uploadsPath, tmpPath string, disk StorageAPI)
|
||||
if wErr = disk.AppendFile(minioMetaTmpBucket, tmpPath, uplBytes); wErr != nil {
|
||||
return traceError(wErr)
|
||||
}
|
||||
wErr = disk.RenameFile(minioMetaTmpBucket, tmpPath, minioMetaBucket, uploadsPath)
|
||||
wErr = disk.RenameFile(minioMetaTmpBucket, tmpPath, minioMetaMultipartBucket, uploadsPath)
|
||||
if wErr != nil {
|
||||
if dErr := disk.DeleteFile(minioMetaTmpBucket, tmpPath); dErr != nil {
|
||||
// we return the most recent error.
|
||||
@ -133,7 +133,7 @@ func cleanupUploadedParts(bucket, object, uploadID string, storageDisks ...Stora
|
||||
var wg = &sync.WaitGroup{}
|
||||
|
||||
// Construct uploadIDPath.
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
|
||||
// Cleanup uploadID for all disks.
|
||||
for index, disk := range storageDisks {
|
||||
@ -145,7 +145,7 @@ func cleanupUploadedParts(bucket, object, uploadID string, storageDisks ...Stora
|
||||
// Cleanup each uploadID in a routine.
|
||||
go func(index int, disk StorageAPI) {
|
||||
defer wg.Done()
|
||||
err := cleanupDir(disk, minioMetaBucket, uploadIDPath)
|
||||
err := cleanupDir(disk, minioMetaMultipartBucket, uploadIDPath)
|
||||
if err != nil {
|
||||
errs[index] = err
|
||||
return
|
||||
|
@ -33,6 +33,8 @@ const (
|
||||
minioMetaBucket = ".minio.sys"
|
||||
// Multipart meta prefix.
|
||||
mpartMetaPrefix = "multipart"
|
||||
// Minio Multipart meta prefix.
|
||||
minioMetaMultipartBucket = minioMetaBucket + "/" + mpartMetaPrefix
|
||||
// Minio Tmp meta prefix.
|
||||
minioMetaTmpBucket = minioMetaBucket + "/tmp"
|
||||
)
|
||||
|
@ -17,7 +17,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"path"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
@ -271,7 +270,7 @@ func (xl xlObjects) DeleteBucket(bucket string) error {
|
||||
return
|
||||
}
|
||||
// Cleanup all the previously incomplete multiparts.
|
||||
err = cleanupDir(disk, path.Join(minioMetaBucket, mpartMetaPrefix), bucket)
|
||||
err = cleanupDir(disk, minioMetaMultipartBucket, bucket)
|
||||
if err != nil {
|
||||
if errorCause(err) == errVolumeNotFound {
|
||||
return
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
// writeUploadJSON - create `uploads.json` or update it with change
|
||||
// described in uCh.
|
||||
func (xl xlObjects) updateUploadJSON(bucket, object string, uCh uploadIDChange) error {
|
||||
uploadsPath := path.Join(mpartMetaPrefix, bucket, object, uploadsJSONFile)
|
||||
uploadsPath := path.Join(bucket, object, uploadsJSONFile)
|
||||
uniqueID := getUUID()
|
||||
tmpUploadsPath := uniqueID
|
||||
|
||||
@ -75,7 +75,7 @@ func (xl xlObjects) updateUploadJSON(bucket, object string, uCh uploadIDChange)
|
||||
if !isDelete[index] {
|
||||
errs[index] = writeUploadJSON(&uploadsJSON, uploadsPath, tmpUploadsPath, disk)
|
||||
} else {
|
||||
wErr := disk.RenameFile(minioMetaBucket, uploadsPath, minioMetaTmpBucket, tmpUploadsPath)
|
||||
wErr := disk.RenameFile(minioMetaMultipartBucket, uploadsPath, minioMetaTmpBucket, tmpUploadsPath)
|
||||
if wErr != nil {
|
||||
errs[index] = traceError(wErr)
|
||||
}
|
||||
@ -110,13 +110,13 @@ func (xl xlObjects) updateUploadJSON(bucket, object string, uCh uploadIDChange)
|
||||
defer wg.Done()
|
||||
if !isDelete[index] {
|
||||
_ = disk.DeleteFile(
|
||||
minioMetaBucket,
|
||||
minioMetaMultipartBucket,
|
||||
uploadsPath,
|
||||
)
|
||||
} else {
|
||||
_ = disk.RenameFile(
|
||||
minioMetaTmpBucket, tmpUploadsPath,
|
||||
minioMetaBucket, uploadsPath,
|
||||
minioMetaMultipartBucket, uploadsPath,
|
||||
)
|
||||
}
|
||||
}(index, disk)
|
||||
@ -167,13 +167,13 @@ func (xl xlObjects) isMultipartUpload(bucket, prefix string) bool {
|
||||
|
||||
// isUploadIDExists - verify if a given uploadID exists and is valid.
|
||||
func (xl xlObjects) isUploadIDExists(bucket, object, uploadID string) bool {
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
return xl.isObject(minioMetaBucket, uploadIDPath)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
return xl.isObject(minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
|
||||
// Removes part given by partName belonging to a mulitpart upload from minioMetaBucket
|
||||
func (xl xlObjects) removeObjectPart(bucket, object, uploadID, partName string) {
|
||||
curpartPath := path.Join(mpartMetaPrefix, bucket, object, uploadID, partName)
|
||||
curpartPath := path.Join(bucket, object, uploadID, partName)
|
||||
wg := sync.WaitGroup{}
|
||||
for i, disk := range xl.storageDisks {
|
||||
if disk == nil {
|
||||
@ -185,7 +185,7 @@ func (xl xlObjects) removeObjectPart(bucket, object, uploadID, partName string)
|
||||
// Ignoring failure to remove parts that weren't present in CompleteMultipartUpload
|
||||
// requests. xl.json is the authoritative source of truth on which parts constitute
|
||||
// the object. The presence of parts that don't belong in the object doesn't affect correctness.
|
||||
_ = disk.DeleteFile(minioMetaBucket, curpartPath)
|
||||
_ = disk.DeleteFile(minioMetaMultipartBucket, curpartPath)
|
||||
}(i, disk)
|
||||
}
|
||||
wg.Wait()
|
||||
@ -193,12 +193,12 @@ func (xl xlObjects) removeObjectPart(bucket, object, uploadID, partName string)
|
||||
|
||||
// statPart - returns fileInfo structure for a successful stat on part file.
|
||||
func (xl xlObjects) statPart(bucket, object, uploadID, partName string) (fileInfo FileInfo, err error) {
|
||||
partNamePath := path.Join(mpartMetaPrefix, bucket, object, uploadID, partName)
|
||||
partNamePath := path.Join(bucket, object, uploadID, partName)
|
||||
for _, disk := range xl.getLoadBalancedDisks() {
|
||||
if disk == nil {
|
||||
continue
|
||||
}
|
||||
fileInfo, err = disk.StatFile(minioMetaBucket, partNamePath)
|
||||
fileInfo, err = disk.StatFile(minioMetaMultipartBucket, partNamePath)
|
||||
if err == nil {
|
||||
return fileInfo, nil
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
}
|
||||
|
||||
// Not using path.Join() as it strips off the trailing '/'.
|
||||
multipartPrefixPath := pathJoin(mpartMetaPrefix, bucket, prefix)
|
||||
multipartPrefixPath := pathJoin(bucket, prefix)
|
||||
if prefix == "" {
|
||||
// Should have a trailing "/" if prefix is ""
|
||||
// For ex. multipartPrefixPath should be "multipart/bucket/" if prefix is ""
|
||||
@ -56,7 +56,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
}
|
||||
multipartMarkerPath := ""
|
||||
if keyMarker != "" {
|
||||
multipartMarkerPath = pathJoin(mpartMetaPrefix, bucket, keyMarker)
|
||||
multipartMarkerPath = pathJoin(bucket, keyMarker)
|
||||
}
|
||||
var uploads []uploadMetadata
|
||||
var err error
|
||||
@ -65,8 +65,8 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
// uploadIDMarker first.
|
||||
if uploadIDMarker != "" {
|
||||
// hold lock on keyMarker path
|
||||
keyMarkerLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, keyMarker))
|
||||
keyMarkerLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, keyMarker))
|
||||
keyMarkerLock.RLock()
|
||||
for _, disk := range xl.getLoadBalancedDisks() {
|
||||
if disk == nil {
|
||||
@ -92,12 +92,12 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
heal := false // true only for xl.ListObjectsHeal
|
||||
// Validate if we need to list further depending on maxUploads.
|
||||
if maxUploads > 0 {
|
||||
walkerCh, walkerDoneCh = xl.listPool.Release(listParams{minioMetaBucket, recursive, multipartMarkerPath, multipartPrefixPath, heal})
|
||||
walkerCh, walkerDoneCh = xl.listPool.Release(listParams{minioMetaMultipartBucket, recursive, multipartMarkerPath, multipartPrefixPath, heal})
|
||||
if walkerCh == nil {
|
||||
walkerDoneCh = make(chan struct{})
|
||||
isLeaf := xl.isMultipartUpload
|
||||
listDir := listDirFactory(isLeaf, xlTreeWalkIgnoredErrs, xl.getLoadBalancedDisks()...)
|
||||
walkerCh = startTreeWalk(minioMetaBucket, multipartPrefixPath, multipartMarkerPath, recursive, listDir, isLeaf, walkerDoneCh)
|
||||
walkerCh = startTreeWalk(minioMetaMultipartBucket, multipartPrefixPath, multipartMarkerPath, recursive, listDir, isLeaf, walkerDoneCh)
|
||||
}
|
||||
// Collect uploads until we have reached maxUploads count to 0.
|
||||
for maxUploads > 0 {
|
||||
@ -115,7 +115,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
}
|
||||
return ListMultipartsInfo{}, err
|
||||
}
|
||||
entry := strings.TrimPrefix(walkResult.entry, retainSlash(pathJoin(mpartMetaPrefix, bucket)))
|
||||
entry := strings.TrimPrefix(walkResult.entry, retainSlash(bucket))
|
||||
// For an entry looking like a directory, store and
|
||||
// continue the loop not need to fetch uploads.
|
||||
if strings.HasSuffix(walkResult.entry, slashSeparator) {
|
||||
@ -135,8 +135,8 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
|
||||
// For the new object entry we get all its
|
||||
// pending uploadIDs.
|
||||
entryLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, entry))
|
||||
entryLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, entry))
|
||||
entryLock.RLock()
|
||||
var disk StorageAPI
|
||||
for _, disk = range xl.getLoadBalancedDisks() {
|
||||
@ -281,13 +281,13 @@ func (xl xlObjects) newMultipartUpload(bucket string, object string, meta map[st
|
||||
|
||||
// This lock needs to be held for any changes to the directory
|
||||
// contents of ".minio.sys/multipart/object/"
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object))
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object))
|
||||
objectMPartPathLock.Lock()
|
||||
defer objectMPartPathLock.Unlock()
|
||||
|
||||
uploadID := getUUID()
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
tempUploadIDPath := uploadID
|
||||
// Write updated `xl.json` to all disks.
|
||||
if err := writeSameXLMetadata(xl.storageDisks, minioMetaTmpBucket, tempUploadIDPath, xlMeta, xl.writeQuorum, xl.readQuorum); err != nil {
|
||||
@ -300,8 +300,8 @@ func (xl xlObjects) newMultipartUpload(bucket string, object string, meta map[st
|
||||
|
||||
// Attempt to rename temp upload object to actual upload path
|
||||
// object
|
||||
if rErr := renameObject(xl.storageDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaBucket, uploadIDPath, xl.writeQuorum); rErr != nil {
|
||||
return "", toObjectErr(rErr, minioMetaBucket, uploadIDPath)
|
||||
if rErr := renameObject(xl.storageDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaMultipartBucket, uploadIDPath, xl.writeQuorum); rErr != nil {
|
||||
return "", toObjectErr(rErr, minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
|
||||
initiated := time.Now().UTC()
|
||||
@ -358,10 +358,10 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
|
||||
var partsMetadata []xlMetaV1
|
||||
var errs []error
|
||||
uploadIDPath := pathJoin(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := pathJoin(bucket, object, uploadID)
|
||||
|
||||
// pre-check upload id lock.
|
||||
preUploadIDLock := nsMutex.NewNSLock(minioMetaBucket, uploadIDPath)
|
||||
preUploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath)
|
||||
preUploadIDLock.RLock()
|
||||
// Validates if upload ID exists.
|
||||
if !xl.isUploadIDExists(bucket, object, uploadID) {
|
||||
@ -369,7 +369,7 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
return "", traceError(InvalidUploadID{UploadID: uploadID})
|
||||
}
|
||||
// Read metadata associated with the object from all disks.
|
||||
partsMetadata, errs = readAllXLMetadata(xl.storageDisks, minioMetaBucket,
|
||||
partsMetadata, errs = readAllXLMetadata(xl.storageDisks, minioMetaMultipartBucket,
|
||||
uploadIDPath)
|
||||
if !isDiskQuorum(errs, xl.writeQuorum) {
|
||||
preUploadIDLock.RUnlock()
|
||||
@ -471,7 +471,7 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
}
|
||||
|
||||
// post-upload check (write) lock
|
||||
postUploadIDLock := nsMutex.NewNSLock(minioMetaBucket, uploadIDPath)
|
||||
postUploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket, uploadIDPath)
|
||||
postUploadIDLock.Lock()
|
||||
defer postUploadIDLock.Unlock()
|
||||
|
||||
@ -482,13 +482,13 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
|
||||
// Rename temporary part file to its final location.
|
||||
partPath := path.Join(uploadIDPath, partSuffix)
|
||||
err = renamePart(onlineDisks, minioMetaTmpBucket, tmpPartPath, minioMetaBucket, partPath, xl.writeQuorum)
|
||||
err = renamePart(onlineDisks, minioMetaTmpBucket, tmpPartPath, minioMetaMultipartBucket, partPath, xl.writeQuorum)
|
||||
if err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, partPath)
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, partPath)
|
||||
}
|
||||
|
||||
// Read metadata again because it might be updated with parallel upload of another part.
|
||||
partsMetadata, errs = readAllXLMetadata(onlineDisks, minioMetaBucket, uploadIDPath)
|
||||
partsMetadata, errs = readAllXLMetadata(onlineDisks, minioMetaMultipartBucket, uploadIDPath)
|
||||
if !isDiskQuorum(errs, xl.writeQuorum) {
|
||||
return "", toObjectErr(traceError(errXLWriteQuorum), bucket, object)
|
||||
}
|
||||
@ -528,9 +528,9 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
if err = writeUniqueXLMetadata(onlineDisks, minioMetaTmpBucket, tempXLMetaPath, partsMetadata, xl.writeQuorum); err != nil {
|
||||
return "", toObjectErr(err, minioMetaTmpBucket, tempXLMetaPath)
|
||||
}
|
||||
rErr := commitXLMetadata(onlineDisks, minioMetaTmpBucket, tempXLMetaPath, minioMetaBucket, uploadIDPath, xl.writeQuorum)
|
||||
rErr := commitXLMetadata(onlineDisks, minioMetaTmpBucket, tempXLMetaPath, minioMetaMultipartBucket, uploadIDPath, xl.writeQuorum)
|
||||
if rErr != nil {
|
||||
return "", toObjectErr(rErr, minioMetaBucket, uploadIDPath)
|
||||
return "", toObjectErr(rErr, minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
|
||||
// Return success.
|
||||
@ -542,11 +542,11 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s
|
||||
func (xl xlObjects) listObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, error) {
|
||||
result := ListPartsInfo{}
|
||||
|
||||
uploadIDPath := path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := path.Join(bucket, object, uploadID)
|
||||
|
||||
xlParts, err := xl.readXLMetaParts(minioMetaBucket, uploadIDPath)
|
||||
xlParts, err := xl.readXLMetaParts(minioMetaMultipartBucket, uploadIDPath)
|
||||
if err != nil {
|
||||
return ListPartsInfo{}, toObjectErr(err, minioMetaBucket, uploadIDPath)
|
||||
return ListPartsInfo{}, toObjectErr(err, minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
|
||||
// Populate the result stub.
|
||||
@ -622,8 +622,8 @@ func (xl xlObjects) ListObjectParts(bucket, object, uploadID string, partNumberM
|
||||
|
||||
// Hold lock so that there is no competing
|
||||
// abort-multipart-upload or complete-multipart-upload.
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object, uploadID))
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object, uploadID))
|
||||
uploadIDLock.Lock()
|
||||
defer uploadIDLock.Unlock()
|
||||
|
||||
@ -662,8 +662,8 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
//
|
||||
// 2) no one does a parallel complete-multipart-upload on this
|
||||
// multipart upload
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object, uploadID))
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object, uploadID))
|
||||
uploadIDLock.Lock()
|
||||
defer uploadIDLock.Unlock()
|
||||
|
||||
@ -676,10 +676,10 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
return "", err
|
||||
}
|
||||
|
||||
uploadIDPath := pathJoin(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath := pathJoin(bucket, object, uploadID)
|
||||
|
||||
// Read metadata associated with the object from all disks.
|
||||
partsMetadata, errs := readAllXLMetadata(xl.storageDisks, minioMetaBucket, uploadIDPath)
|
||||
partsMetadata, errs := readAllXLMetadata(xl.storageDisks, minioMetaMultipartBucket, uploadIDPath)
|
||||
// Do we have writeQuorum?.
|
||||
if !isDiskQuorum(errs, xl.writeQuorum) {
|
||||
return "", toObjectErr(traceError(errXLWriteQuorum), bucket, object)
|
||||
@ -760,7 +760,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
|
||||
// Save successfully calculated md5sum.
|
||||
xlMeta.Meta["md5Sum"] = s3MD5
|
||||
uploadIDPath = path.Join(mpartMetaPrefix, bucket, object, uploadID)
|
||||
uploadIDPath = path.Join(bucket, object, uploadID)
|
||||
tempUploadIDPath := uploadID
|
||||
|
||||
// Update all xl metadata, make sure to not modify fields like
|
||||
@ -775,9 +775,9 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
if err = writeUniqueXLMetadata(onlineDisks, minioMetaTmpBucket, tempUploadIDPath, partsMetadata, xl.writeQuorum); err != nil {
|
||||
return "", toObjectErr(err, minioMetaTmpBucket, tempUploadIDPath)
|
||||
}
|
||||
rErr := commitXLMetadata(onlineDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaBucket, uploadIDPath, xl.writeQuorum)
|
||||
rErr := commitXLMetadata(onlineDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaMultipartBucket, uploadIDPath, xl.writeQuorum)
|
||||
if rErr != nil {
|
||||
return "", toObjectErr(rErr, minioMetaBucket, uploadIDPath)
|
||||
return "", toObjectErr(rErr, minioMetaMultipartBucket, uploadIDPath)
|
||||
}
|
||||
|
||||
// Hold write lock on the destination before rename.
|
||||
@ -823,7 +823,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
}
|
||||
|
||||
// Rename the multipart object to final location.
|
||||
if err = renameObject(onlineDisks, minioMetaBucket, uploadIDPath, bucket, object, xl.writeQuorum); err != nil {
|
||||
if err = renameObject(onlineDisks, minioMetaMultipartBucket, uploadIDPath, bucket, object, xl.writeQuorum); err != nil {
|
||||
return "", toObjectErr(err, bucket, object)
|
||||
}
|
||||
|
||||
@ -833,14 +833,14 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
// Hold the lock so that two parallel
|
||||
// complete-multipart-uploads do not leave a stale
|
||||
// uploads.json behind.
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object))
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object))
|
||||
objectMPartPathLock.Lock()
|
||||
defer objectMPartPathLock.Unlock()
|
||||
|
||||
// remove entry from uploads.json with quorum
|
||||
if err = xl.updateUploadJSON(bucket, object, uploadIDChange{uploadID: uploadID, isRemove: true}); err != nil {
|
||||
return "", toObjectErr(err, minioMetaBucket, path.Join(mpartMetaPrefix, bucket, object))
|
||||
return "", toObjectErr(err, minioMetaMultipartBucket, path.Join(bucket, object))
|
||||
}
|
||||
|
||||
// Return md5sum.
|
||||
@ -859,8 +859,8 @@ func (xl xlObjects) abortMultipartUpload(bucket, object, uploadID string) (err e
|
||||
|
||||
// hold lock so we don't compete with a complete, or abort
|
||||
// multipart request.
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object))
|
||||
objectMPartPathLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object))
|
||||
objectMPartPathLock.Lock()
|
||||
defer objectMPartPathLock.Unlock()
|
||||
|
||||
@ -898,8 +898,8 @@ func (xl xlObjects) AbortMultipartUpload(bucket, object, uploadID string) error
|
||||
|
||||
// Hold lock so that there is no competing
|
||||
// complete-multipart-upload or put-object-part.
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaBucket,
|
||||
pathJoin(mpartMetaPrefix, bucket, object, uploadID))
|
||||
uploadIDLock := nsMutex.NewNSLock(minioMetaMultipartBucket,
|
||||
pathJoin(bucket, object, uploadID))
|
||||
uploadIDLock.Lock()
|
||||
defer uploadIDLock.Unlock()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user