api: CopyObject pipe should be closed pro-actively upon error. (#2625)

Fixes a deadlock reproduced while running s3verify during
RemoveObject().  Previously held lock by GetObject() inside
the go-routine was never relenquished.
This commit is contained in:
Harshavardhana 2016-09-06 02:23:32 -07:00 committed by GitHub
parent b291dbe9c5
commit afe874f15a

View File

@ -334,10 +334,14 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
// Create the object. // Create the object.
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, size, pipeReader, metadata) md5Sum, err := api.ObjectAPI.PutObject(bucket, object, size, pipeReader, metadata)
if err != nil { if err != nil {
// Close the this end of the pipe upon error in PutObject.
pipeReader.CloseWithError(err)
errorIf(err, "Unable to create an object.") errorIf(err, "Unable to create an object.")
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path) writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return return
} }
// Explicitly close the reader, before fetching object info.
pipeReader.Close()
objInfo, err = api.ObjectAPI.GetObjectInfo(bucket, object) objInfo, err = api.ObjectAPI.GetObjectInfo(bucket, object)
if err != nil { if err != nil {
@ -352,8 +356,6 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
setCommonHeaders(w) setCommonHeaders(w)
// write success response. // write success response.
writeSuccessResponse(w, encodedSuccessResponse) writeSuccessResponse(w, encodedSuccessResponse)
// Explicitly close the reader, to avoid fd leaks.
pipeReader.Close()
if eventN.IsBucketNotificationSet(bucket) { if eventN.IsBucketNotificationSet(bucket) {
// Notify object created event. // Notify object created event.