From 52d028ffe933a703786b078ca22444e8536d09c5 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov <evgeniy@nspcc.ru> Date: Wed, 12 Jan 2022 18:59:18 +0300 Subject: [PATCH] Fix readonly file mapping on windows `CreateFileMapping` tries to extend the file to the size of mapping which leads to failure if database was opened in readonly and calculated mmap size is bigger than the file size. Providing 0 to `MapViewOfFile` will create a view which has size of mapping, i.e. file-size in read-only mode and full size if file was truncated. Also, swap `sizehi` and `sizelo` names to reflect windows API docs. This was changed in 1c97a490d for seemingly no reason. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru> --- bolt_windows.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bolt_windows.go b/bolt_windows.go index 09e00b6..afc1a29 100644 --- a/bolt_windows.go +++ b/bolt_windows.go @@ -62,23 +62,25 @@ func funlock(db *DB) error { // mmap memory maps a DB's data file. // Based on: https://github.com/edsrzf/mmap-go func mmap(db *DB, sz int) error { + var sizelo, sizehi uint32 + if !db.readOnly { // Truncate the database to the size of the mmap. if err := db.file.Truncate(int64(sz)); err != nil { return fmt.Errorf("truncate: %s", err) } + sizehi = uint32(sz >> 32) + sizelo = uint32(sz) & 0xffffffff } // Open a file mapping handle. - sizelo := uint32(sz >> 32) - sizehi := uint32(sz) & 0xffffffff - h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil) + h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizehi, sizelo, nil) if h == 0 { return os.NewSyscallError("CreateFileMapping", errno) } // Create the memory map. - addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(sz)) + addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0) if addr == 0 { return os.NewSyscallError("MapViewOfFile", errno) }