diff --git a/dir_unix.go b/dir_unix.go index 8f7be0f..a946231 100644 --- a/dir_unix.go +++ b/dir_unix.go @@ -15,5 +15,5 @@ import ( func (defaultFS) OpenDir(name string) (File, error) { f, err := os.OpenFile(name, syscall.O_CLOEXEC, 0) - return f, errors.WithStack(err) + return &fileCompat{f}, errors.WithStack(err) } diff --git a/error_fs.go b/error_fs.go index b89e5a1..5fcd815 100644 --- a/error_fs.go +++ b/error_fs.go @@ -327,3 +327,29 @@ func (f *errorFile) Sync() error { } return f.file.Sync() } + +func (f *errorFile) Preallocate(offset, length int64) error { + return nil +} + +func (f *errorFile) SyncTo(length int64) (fullSync bool, err error) { + return true, f.Sync() +} + +func (f *errorFile) SyncData() error { + return f.Sync() +} + +func (f *errorFile) Prefetch(offset int64, length int64) error { + return nil +} + +func (f *errorFile) Fd() uintptr { + type fd interface { + Fd() uintptr + } + if d, ok := f.file.(fd); ok { + return d.Fd() + } + return InvalidFd +} diff --git a/mem_fs.go b/mem_fs.go index fc41f4c..1780990 100644 --- a/mem_fs.go +++ b/mem_fs.go @@ -763,3 +763,23 @@ func (f *memFile) Sync() error { } return nil } + +func (f *memFile) Preallocate(offset, length int64) error { + return nil +} + +func (f *memFile) SyncTo(length int64) (fullSync bool, err error) { + return true, f.Sync() +} + +func (f *memFile) SyncData() error { + return f.Sync() +} + +func (f *memFile) Prefetch(offset int64, length int64) error { + return nil +} + +func (f *memFile) Fd() uintptr { + return InvalidFd +} diff --git a/syncing_file.go b/syncing_file.go index ab337e7..942f6e0 100644 --- a/syncing_file.go +++ b/syncing_file.go @@ -167,3 +167,26 @@ func (f *syncingFile) Close() error { } return f.File.Close() } + +func (f *syncingFile) Preallocate(offset, length int64) error { + return nil +} + +func (f *syncingFile) SyncTo(length int64) (fullSync bool, err error) { + return true, f.Sync() +} + +func (f *syncingFile) SyncData() error { + return f.Sync() +} + +func (f *syncingFile) Prefetch(offset int64, length int64) error { + return nil +} + +func (f *syncingFile) Fd() uintptr { + if f.fd != 0 { + return f.fd + } + return InvalidFd +} diff --git a/vfs.go b/vfs.go index b93c652..c6df15a 100644 --- a/vfs.go +++ b/vfs.go @@ -28,6 +28,11 @@ type File interface { io.WriterAt Stat() (os.FileInfo, error) Sync() error + Preallocate(offset, length int64) error + SyncTo(length int64) (fullSync bool, err error) + SyncData() error + Prefetch(offset int64, length int64) error + Fd() uintptr } // OpenOption provide an interface to do work on file handles in the Open() @@ -137,6 +142,32 @@ type DiskUsage struct { UsedBytes uint64 } +const InvalidFd uintptr = ^(uintptr(0)) + +type fileCompat struct { + *os.File +} + +func (f *fileCompat) Preallocate(offset, length int64) error { + return nil +} + +func (f *fileCompat) SyncTo(length int64) (fullSync bool, err error) { + return true, f.Sync() +} + +func (f *fileCompat) SyncData() error { + return f.Sync() +} + +func (f *fileCompat) Prefetch(offset int64, length int64) error { + return nil +} + +func (f *fileCompat) Fd() uintptr { + return f.File.Fd() +} + // Default is a FS implementation backed by the underlying operating system's // file system. var Default FS = defaultFS{} @@ -145,7 +176,7 @@ type defaultFS struct{} func (defaultFS) Create(name string) (File, error) { f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC|syscall.O_CLOEXEC, 0666) - return f, errors.WithStack(err) + return &fileCompat{f}, errors.WithStack(err) } func (defaultFS) Link(oldname, newname string) error { @@ -154,18 +185,19 @@ func (defaultFS) Link(oldname, newname string) error { func (defaultFS) Open(name string, opts ...OpenOption) (File, error) { file, err := os.OpenFile(name, os.O_RDONLY|syscall.O_CLOEXEC, 0) + f := &fileCompat{file} if err != nil { return nil, errors.WithStack(err) } for _, opt := range opts { - opt.Apply(file) + opt.Apply(f) } - return file, nil + return f, nil } func (defaultFS) OpenForAppend(name string) (File, error) { f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND|syscall.O_CLOEXEC, 0) - return f, errors.WithStack(err) + return &fileCompat{f}, errors.WithStack(err) } func (defaultFS) Remove(name string) error { @@ -185,7 +217,7 @@ func (fs defaultFS) ReuseForWrite(oldname, newname string) (File, error) { return nil, errors.WithStack(err) } f, err := os.OpenFile(newname, os.O_RDWR|os.O_CREATE|syscall.O_CLOEXEC, 0666) - return f, errors.WithStack(err) + return &fileCompat{f}, errors.WithStack(err) } func (defaultFS) MkdirAll(dir string, perm os.FileMode) error {