F2FS atomic writes. (#66)

https://sqlite.org/cgi/src/technote/714f6cbbf7
This commit is contained in:
Nuno Cruces
2024-03-21 13:59:47 +00:00
committed by GitHub
parent 36583542e1
commit 617982f947
8 changed files with 75 additions and 6 deletions

View File

@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
echo 'set -euo pipefail' > test.sh

View File

@@ -13,7 +13,7 @@ elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
fi
# Download tools
mkdir -p tools
mkdir -p tools/
[ -d "tools/wasi-sdk"* ] || curl -#L "$WASI_SDK" | tar xzC tools &
[ -d "tools/binaryen-version"* ] || curl -#L "$BINARYEN" | tar xzC tools &
wait

View File

@@ -99,8 +99,8 @@ func instantiateSQLite() (sqlt *sqlite, err error) {
}
sqlt.freer = util.ReadUint32(sqlt.mod, uint32(global.Get()))
if err != nil {
return nil, err
if sqlt.freer == 0 {
return nil, util.BadBinaryErr
}
return sqlt, nil
}

BIN
tests/testdata/f2fs.img.gz vendored Normal file

Binary file not shown.

21
tests/testdata/f2fs.sh vendored Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
cd -P -- "$(dirname -- "$0")"
ROOT=../../
if mountpoint -q f2fs/; then
sudo umount f2fs/
fi
mkdir -p f2fs/
gunzip -c f2fs.img.gz > f2fs.img
sudo mount -nv -o loop f2fs.img f2fs/
mkdir -p f2fs/tmp/
go test -c "$ROOT/tests" -coverpkg github.com/ncruces/go-sqlite3/...
TMPDIR=f2fs/tmp/ ./tests.test -test.v -test.short -test.coverprofile cover.out
go tool cover -html cover.out
sudo umount f2fs/
rm -r f2fs/ f2fs.img cover.out *.test

View File

@@ -173,10 +173,14 @@ func (*vfsFile) SectorSize() int {
}
func (f *vfsFile) DeviceCharacteristics() DeviceCharacteristic {
if f.psow {
return IOCAP_POWERSAFE_OVERWRITE
var res DeviceCharacteristic
if osBatchAtomic(f.File) {
res |= IOCAP_BATCH_ATOMIC
}
return 0
if f.psow {
res |= IOCAP_POWERSAFE_OVERWRITE
}
return res
}
func (f *vfsFile) SizeHint(size int64) error {

34
vfs/os_f2fs_linux.go Normal file
View File

@@ -0,0 +1,34 @@
//go:build (amd64 || arm64) && !sqlite3_nosys
package vfs
import (
"os"
"golang.org/x/sys/unix"
)
const (
_F2FS_IOC_START_ATOMIC_WRITE = 62721
_F2FS_IOC_COMMIT_ATOMIC_WRITE = 62722
_F2FS_IOC_ABORT_ATOMIC_WRITE = 62725
_F2FS_IOC_GET_FEATURES = 2147808524
_F2FS_FEATURE_ATOMIC_WRITE = 4
)
func osBatchAtomic(file *os.File) bool {
flags, err := unix.IoctlGetInt(int(file.Fd()), _F2FS_IOC_GET_FEATURES)
return err == nil && flags&_F2FS_FEATURE_ATOMIC_WRITE != 0
}
func (f *vfsFile) BeginAtomicWrite() error {
return unix.IoctlSetInt(int(f.Fd()), _F2FS_IOC_START_ATOMIC_WRITE, 0)
}
func (f *vfsFile) CommitAtomicWrite() error {
return unix.IoctlSetInt(int(f.Fd()), _F2FS_IOC_COMMIT_ATOMIC_WRITE, 0)
}
func (f *vfsFile) RollbackAtomicWrite() error {
return unix.IoctlSetInt(int(f.Fd()), _F2FS_IOC_ABORT_ATOMIC_WRITE, 0)
}

9
vfs/os_std_atomic.go Normal file
View File

@@ -0,0 +1,9 @@
//go:build !linux || !(amd64 || arm64) || sqlite3_nosys
package vfs
import "os"
func osBatchAtomic(*os.File) bool {
return false
}