@@ -424,7 +424,7 @@ func (db *DB) hasSyncedFreelist() bool {
424424
425425// mmap opens the underlying memory-mapped file and initializes the meta references.
426426// minsz is the minimum size that the new mmap can be.
427- func (db * DB ) mmap (minsz int ) error {
427+ func (db * DB ) mmap (minsz int ) ( err error ) {
428428 db .mmaplock .Lock ()
429429 defer db .mmaplock .Unlock ()
430430
@@ -459,17 +459,27 @@ func (db *DB) mmap(minsz int) error {
459459 }
460460
461461 // Unmap existing data before continuing.
462- if err : = db .munmap (); err != nil {
462+ if err = db .munmap (); err != nil {
463463 return err
464464 }
465465
466466 // Memory-map the data file as a byte slice.
467467 // gofail: var mapError string
468468 // return errors.New(mapError)
469- if err : = mmap (db , size ); err != nil {
469+ if err = mmap (db , size ); err != nil {
470470 return err
471471 }
472472
473+ // Perform unmmap on any error to reset all data fields:
474+ // dataref, data, datasz, meta0 and meta1.
475+ defer func () {
476+ if err != nil {
477+ if unmapErr := db .munmap (); unmapErr != nil {
478+ err = fmt .Errorf ("%w; rollback unmap also failed: %v" , err , unmapErr )
479+ }
480+ }
481+ }()
482+
473483 if db .Mlock {
474484 // Don't allow swapping of data file
475485 if err := db .mlock (fileSize ); err != nil {
@@ -553,13 +563,17 @@ func (db *DB) mmapSize(size int) (int, error) {
553563}
554564
555565func (db * DB ) munlock (fileSize int ) error {
566+ // gofail: var munlockError string
567+ // return errors.New(munlockError)
556568 if err := munlock (db , fileSize ); err != nil {
557569 return fmt .Errorf ("munlock error: " + err .Error ())
558570 }
559571 return nil
560572}
561573
562574func (db * DB ) mlock (fileSize int ) error {
575+ // gofail: var mlockError string
576+ // return errors.New(mlockError)
563577 if err := mlock (db , fileSize ); err != nil {
564578 return fmt .Errorf ("mlock error: " + err .Error ())
565579 }
0 commit comments