From dbaed53b9a558f314d3b98b5dcb9ac69e6f0807a Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Fri, 10 Mar 2023 14:02:34 +0000 Subject: [PATCH] Sync and delete improvements. --- const.go | 25 +++++++++++++++++-------- vfs.go | 19 +++++++++++-------- vfs_test.go | 2 +- vfs_unix.go | 15 +++++++++++++++ vfs_windows.go | 2 +- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/const.go b/const.go index 7edd141..94497bc 100644 --- a/const.go +++ b/const.go @@ -133,6 +133,7 @@ const ( CONSTRAINT_DATATYPE ExtendedErrorCode = xErrorCode(CONSTRAINT) | (12 << 8) NOTICE_RECOVER_WAL ExtendedErrorCode = xErrorCode(NOTICE) | (1 << 8) NOTICE_RECOVER_ROLLBACK ExtendedErrorCode = xErrorCode(NOTICE) | (2 << 8) + NOTICE_RBU ExtendedErrorCode = xErrorCode(NOTICE) | (3 << 8) WARNING_AUTOINDEX ExtendedErrorCode = xErrorCode(WARNING) | (1 << 8) AUTH_USER ExtendedErrorCode = xErrorCode(AUTH) | (1 << 8) ) @@ -167,14 +168,6 @@ const ( OPEN_EXRESCODE OpenFlag = 0x02000000 /* Extended result codes */ ) -type _AccessFlag uint32 - -const ( - _ACCESS_EXISTS _AccessFlag = 0 - _ACCESS_READWRITE _AccessFlag = 1 /* Used by PRAGMA temp_store_directory */ - _ACCESS_READ _AccessFlag = 2 /* Unused */ -) - // PrepareFlag is a flag that can be passed to [Conn.PrepareFlags]. // // https://www.sqlite.org/c3ref/c_prepare_normalize.html @@ -216,3 +209,19 @@ func (t Datatype) String() string { } return strconv.FormatUint(uint64(t), 10) } + +type _AccessFlag uint32 + +const ( + _ACCESS_EXISTS _AccessFlag = 0 + _ACCESS_READWRITE _AccessFlag = 1 /* Used by PRAGMA temp_store_directory */ + _ACCESS_READ _AccessFlag = 2 /* Unused */ +) + +type _SyncFlag uint32 + +const ( + _SYNC_NORMAL _SyncFlag = 0x00002 + _SYNC_FULL _SyncFlag = 0x00003 + _SYNC_DATAONLY _SyncFlag = 0x00010 +) diff --git a/vfs.go b/vfs.go index 2f9b595..bd2228a 100644 --- a/vfs.go +++ b/vfs.go @@ -165,19 +165,20 @@ func vfsDelete(ctx context.Context, mod api.Module, pVfs, zPath, syncDir uint32) path := memory{mod}.readString(zPath, _MAX_PATHNAME) err := os.Remove(path) if errors.Is(err, fs.ErrNotExist) { - return _OK + return uint32(IOERR_DELETE_NOENT) } if err != nil { return uint32(IOERR_DELETE) } if runtime.GOOS != "windows" && syncDir != 0 { f, err := os.Open(filepath.Dir(path)) - if err == nil { - err = f.Sync() - f.Close() - } if err != nil { - return uint32(IOERR_DELETE) + return _OK + } + defer f.Close() + err = vfsOS.Sync(f, false, false) + if err != nil { + return uint32(IOERR_DIR_FSYNC) } } return _OK @@ -278,9 +279,11 @@ func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64 return _OK } -func vfsSync(ctx context.Context, mod api.Module, pFile, flags uint32) uint32 { +func vfsSync(ctx context.Context, mod api.Module, pFile uint32, flags _SyncFlag) uint32 { + dataonly := (flags & _SYNC_DATAONLY) != 0 + fullsync := (flags & 0x0f) == _SYNC_FULL file := vfsFile.GetOS(ctx, mod, pFile) - err := file.Sync() + err := vfsOS.Sync(file, fullsync, dataonly) if err != nil { return uint32(IOERR_FSYNC) } diff --git a/vfs_test.go b/vfs_test.go index f3e7208..367fbef 100644 --- a/vfs_test.go +++ b/vfs_test.go @@ -165,7 +165,7 @@ func Test_vfsDelete(t *testing.T) { } rc = vfsDelete(ctx, mem.mod, 0, 4, 1) - if rc != _OK { + if rc != uint32(IOERR_DELETE_NOENT) { t.Fatal("returned", rc) } } diff --git a/vfs_unix.go b/vfs_unix.go index 1d8b11d..ef42a14 100644 --- a/vfs_unix.go +++ b/vfs_unix.go @@ -30,6 +30,21 @@ func (vfsOSMethods) Access(path string, flags _AccessFlag) (bool, xErrorCode) { return false, _OK } +func (vfsOSMethods) Sync(file *os.File, fullsync, dataonly bool) error { + if runtime.GOOS == "darwin" && !fullsync { + return unix.Fsync(int(file.Fd())) + } + if runtime.GOOS == "linux" && dataonly { + //lint:ignore SA1019 OK on linux + _, _, err := unix.Syscall(unix.SYS_FDATASYNC, file.Fd(), 0, 0) + if err != 0 { + return err + } + return nil + } + return file.Sync() +} + func (vfsOSMethods) GetExclusiveLock(file *os.File) xErrorCode { // Acquire the EXCLUSIVE lock. return vfsOS.writeLock(file, _SHARED_FIRST, _SHARED_SIZE) diff --git a/vfs_windows.go b/vfs_windows.go index f7ff88f..be7bf42 100644 --- a/vfs_windows.go +++ b/vfs_windows.go @@ -25,7 +25,7 @@ func (vfsOSMethods) OpenFile(name string, flag int, perm fs.FileMode) (*os.File, return os.NewFile(uintptr(r), name), nil } -func (vfsOSMethods) Sync(file *os.File) error { +func (vfsOSMethods) Sync(file *os.File, fullsync, dataonly bool) error { return file.Sync() }