Pass values to closures esp. when passed to defer statement. (#3050)

opsID, a variable on the stack, changes over the course of
Completemultipartupload function in xl-v1-multipart.go.  This was
being used in a function closure which was passed to defer
statement. The variables used in the closure depend on their values at
the time of evaluation which is indeterminate behaviour. It is
incorrect to depend on values of variables on stack at the end of
function, when deferred functions are executed.
master
Krishnan Parthasarathi 8 years ago committed by Harshavardhana
parent e293f079f5
commit 8839c5105a
  1. 6
      cmd/xl-v1-multipart.go

@ -760,19 +760,19 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
// Hold write lock on the destination before rename. // Hold write lock on the destination before rename.
nsMutex.Lock(bucket, object, opsID) nsMutex.Lock(bucket, object, opsID)
defer func() { defer func(curOpsID string) {
// A new complete multipart upload invalidates any // A new complete multipart upload invalidates any
// previously cached object in memory. // previously cached object in memory.
xl.objCache.Delete(path.Join(bucket, object)) xl.objCache.Delete(path.Join(bucket, object))
// This lock also protects the cache namespace. // This lock also protects the cache namespace.
nsMutex.Unlock(bucket, object, opsID) nsMutex.Unlock(bucket, object, curOpsID)
// Prefetch the object from disk by triggering a fake GetObject call // Prefetch the object from disk by triggering a fake GetObject call
// Unlike a regular single PutObject, multipart PutObject is comes in // Unlike a regular single PutObject, multipart PutObject is comes in
// stages and it is harder to cache. // stages and it is harder to cache.
go xl.GetObject(bucket, object, 0, objectSize, ioutil.Discard) go xl.GetObject(bucket, object, 0, objectSize, ioutil.Discard)
}() }(opsID)
// Rename if an object already exists to temporary location. // Rename if an object already exists to temporary location.
uniqueID := getUUID() uniqueID := getUUID()

Loading…
Cancel
Save