Skip to content

Commit

Permalink
headerfs: on Windows, close/truncate/reopen to avoid access denied
Browse files Browse the repository at this point in the history
  • Loading branch information
aakselrod committed Oct 20, 2017
1 parent 3fa0b5a commit a7acec5
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 33 deletions.
33 changes: 0 additions & 33 deletions headerfs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,39 +46,6 @@ func (h *headerStore) readRaw(seekDist int64) ([]byte, error) {
return rawHeader, nil
}

// singleTruncate truncates a single header from the end of the header file.
// This can be used in the case of a re-org to remove the last header from the
// end of the main chain.
//
// TODO(roasbeef): define this and the two methods above on a headerFile
// struct?
func (h *headerStore) singleTruncate() error {
// In order to truncate the file, we'll need to grab the absolute size
// of the file as it stands currently.
fileInfo, err := h.file.Stat()
if err != nil {
return err
}
fileSize := fileInfo.Size()

// Next, we'll determine the number of bytes we need to truncate from
// the end of the file.
var truncateLength int64
switch h.indexType {
case Block:
truncateLength = 80
case RegularFilter:
fallthrough
case ExtendedFilter:
truncateLength = 32
}

// Finally, we'll use both of these values to calculate the new size of
// the file and truncate it accordingly.
newSize := fileSize - truncateLength
return h.file.Truncate(newSize)
}

// readHeader reads a full block header from the flat-file. The header read is
// determined by the hight value.
func (h *BlockHeaderStore) readHeader(height int64) (*wire.BlockHeader, error) {
Expand Down
36 changes: 36 additions & 0 deletions headerfs/truncate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// +build !windows

package headerfs

// singleTruncate truncates a single header from the end of the header file.
// This can be used in the case of a re-org to remove the last header from the
// end of the main chain.
//
// TODO(roasbeef): define this and the two methods above on a headerFile
// struct?
func (h *headerStore) singleTruncate() error {
// In order to truncate the file, we'll need to grab the absolute size
// of the file as it stands currently.
fileInfo, err := h.file.Stat()
if err != nil {
return err
}
fileSize := fileInfo.Size()

// Next, we'll determine the number of bytes we need to truncate from
// the end of the file.
var truncateLength int64
switch h.indexType {
case Block:
truncateLength = 80
case RegularFilter:
fallthrough
case ExtendedFilter:
truncateLength = 32
}

// Finally, we'll use both of these values to calculate the new size of
// the file and truncate it accordingly.
newSize := fileSize - truncateLength
return h.file.Truncate(newSize)
}
53 changes: 53 additions & 0 deletions headerfs/truncate_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// +build windows

package headerfs

import "os"

// singleTruncate truncates a single header from the end of the header file.
// This can be used in the case of a re-org to remove the last header from the
// end of the main chain.
//
// TODO(roasbeef): define this and the two methods above on a headerFile
// struct?
func (h *headerStore) singleTruncate() error {
// In order to truncate the file, we'll need to grab the absolute size
// of the file as it stands currently.
fileInfo, err := h.file.Stat()
if err != nil {
return err
}
fileSize := fileInfo.Size()

// Next, we'll determine the number of bytes we need to truncate from
// the end of the file.
var truncateLength int64
switch h.indexType {
case Block:
truncateLength = 80
case RegularFilter:
fallthrough
case ExtendedFilter:
truncateLength = 32
}

// Finally, we'll use both of these values to calculate the new size of
// the file.
newSize := fileSize - truncateLength

// On Windows, a file can't be truncated while open, even if using a
// file handle to truncate it. This means we have to close, truncate,
// and reopen it.
fileName := h.file.Name()
if err = h.file.Close(); err != nil {
return err
}

if err = os.Truncate(fileName, newSize); err != nil {
return err
}

fileFlags := os.O_RDWR | os.O_APPEND | os.O_CREATE
h.file, err = os.OpenFile(fileName, fileFlags, 0644)
return err
}

0 comments on commit a7acec5

Please sign in to comment.