Source File
fs.go
Belonging Package
github.com/polarsignals/wal/fs
// Copyright (c) HashiCorp, Inc// SPDX-License-Identifier: MPL-2.0package fsimport ()// FS implements the wal.VFS interface using GO's built in OS Filesystem (and a// few helpers).//// TODO if we changed the interface to be Dir centric we could cache the open// dir handle and save some time opening it on each Create in order to fsync.type FS struct {}func () *FS {return &FS{}}// ListDir returns a list of all files in the specified dir in lexicographical// order. If the dir doesn't exist, it must return an error. Empty array with// nil error is assumed to mean that the directory exists and was readable,// but contains no files.func ( *FS) ( string) ([]string, error) {, := ioutil.ReadDir()if != nil {return nil,}:= make([]string, len())for , := range {if .IsDir() {continue}[] = .Name()}return , nil}// Create creates a new file with the given name. If a file with the same name// already exists an error is returned. If a non-zero size is given,// implementations should make a best effort to pre-allocate the file to be// that size. The dir must already exist and be writable to the current// process.func ( *FS) ( string, string, uint64) (types.WritableFile, error) {, := os.OpenFile(filepath.Join(, ), os.O_CREATE|os.O_EXCL|os.O_RDWR, os.FileMode(0644))if != nil {return nil,}// We just created the file. Preallocate it's size.if > 0 {if > math.MaxInt32 {return nil, fmt.Errorf("maximum file size is %d bytes", math.MaxInt32)}if := prealloc(, int64(), true); != nil {.Close()return nil,}}// We don't fsync here for performance reasons. Technically we need to fsync// the file itself to make sure it is really persisted to disk, and you always// need to fsync its parent dir after a creation because fsync doesn't ensure// the directory entry is persisted - a crash could make the file appear to be// missing as there is no directory entry.//// BUT, it doesn't actually matter if this file is crash safe, right up to the// point where we actually commit log data. Since we always fsync the file// when we commit logs, we don't need to again here. That does however leave// the parent dir fsync which must be done after the first fsync to a newly// created file to ensure it survives a crash.//// To handle that, we return a wrapped io.File that will fsync the parent dir// as well the first time Sync is called (and only the first time),:= &File{new: 0,dir: ,File: *,}return , nil}// Delete indicates the file is no longer required. Typically it should be// deleted from the underlying system to free disk space.func ( *FS) ( string, string) error {if := os.Remove(filepath.Join(, )); != nil {return}// Make sure parent directory metadata is fsynced too before we call this// "done".return syncDir()}// OpenReader opens an existing file in read-only mode. If the file doesn't// exist or permission is denied, an error is returned, otherwise no checks// are made about the well-formedness of the file, it may be empty, the wrong// size or corrupt in arbitrary ways.func ( *FS) ( string, string) (types.ReadableFile, error) {return os.OpenFile(filepath.Join(, ), os.O_RDONLY, os.FileMode(0644))}// OpenWriter opens a file in read-write mode. If the file doesn't exist or// permission is denied, an error is returned, otherwise no checks are made// about the well-formedness of the file, it may be empty, the wrong size or// corrupt in arbitrary ways.func ( *FS) ( string, string) (types.WritableFile, error) {return os.OpenFile(filepath.Join(, ), os.O_RDWR, os.FileMode(0644))}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |