From 6bb25854a183f3d3bfa50096f910d3a3984e9834 Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Sun, 18 Jan 2015 08:24:53 -0700 Subject: Add truncate() and sync() on resize. This commit fixes an issue with ext3/ext4 filesystems where metadata file size is not synced when resizing a file. It also resizes the entire resize instead of updating the size during individual page writes. Thanks to @tv42 for the fix. --- bolt_unix.go | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'bolt_unix.go') diff --git a/bolt_unix.go b/bolt_unix.go index 95647a7..e222cfd 100644 --- a/bolt_unix.go +++ b/bolt_unix.go @@ -3,6 +3,7 @@ package bolt import ( + "fmt" "os" "syscall" "time" @@ -41,6 +42,16 @@ func funlock(f *os.File) error { // mmap memory maps a DB's data file. func mmap(db *DB, sz int) error { + // Truncate and fsync to ensure file size metadata is flushed. + // https://github.com/boltdb/bolt/issues/284 + if err := db.file.Truncate(int64(sz)); err != nil { + return fmt.Errorf("file resize error: %s", err) + } + if err := db.file.Sync(); err != nil { + return fmt.Errorf("file sync error: %s", err) + } + + // Map the data file to memory. b, err := syscall.Mmap(int(db.file.Fd()), 0, sz, syscall.PROT_READ, syscall.MAP_SHARED) if err != nil { return err -- cgit v1.2.3