Skip to content

Commit 7a13798

Browse files
committed
Backport perform unmap when failing to mlock or both meta pages corrupted.
Signed-off-by: James Blair <[email protected]>
1 parent ad36005 commit 7a13798

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

db.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

555565
func (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

562574
func (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

Comments
 (0)