Ensure content writer only unlocks resource once
Make close a no-op after commit and disallow committing after close.
@@ -55,6 +55,10 @@ func (w *writer) Write(p []byte) (n int, err error) {
}
func (w *writer) Commit(size int64, expected digest.Digest, opts ...content.Opt) error {
+ if w.fp == nil {
+ return errors.Wrap(errdefs.ErrFailedPrecondition, "cannot commit on closed writer")
+ }
+
if err := w.fp.Sync(); err != nil {
return errors.Wrap(err, "sync failed")
}
@@ -115,8 +119,8 @@ func (w *writer) Commit(size int64, expected digest.Digest, opts ...content.Opt)
return err
}
- unlock(w.ref)
w.fp = nil
+ unlock(w.ref)
return nil
}
@@ -130,12 +134,13 @@ func (w *writer) Commit(size int64, expected digest.Digest, opts ...content.Opt)
//
// To abandon a transaction completely, first call close then `Store.Remove` to
// clean up the associated resources.
-func (cw *writer) Close() (err error) {
- unlock(cw.ref)
-
- if cw.fp != nil {
- cw.fp.Sync()
- return cw.fp.Close()
+func (w *writer) Close() (err error) {
+ if w.fp != nil {
+ w.fp.Sync()
+ err = w.fp.Close()
+ w.fp = nil
+ unlock(w.ref)
+ return
}
return nil
