Persist: Make sure data is flushed to disk on save

(i.e., do the usual flush & fsync dance, because FAT32 is the worst).
pull/9710/head
NiLuJe 2 years ago
parent b523c2e8b9
commit b656b9f5af

@ -2,12 +2,14 @@ local bitser = require("ffi/bitser")
local buffer = require("string.buffer") local buffer = require("string.buffer")
local dump = require("dump") local dump = require("dump")
local ffi = require("ffi") local ffi = require("ffi")
local ffiUtil = require("ffi/util")
local lfs = require("libs/libkoreader-lfs") local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local serpent = require("ffi/serpent") local serpent = require("ffi/serpent")
local zstd = require("ffi/zstd") local zstd = require("ffi/zstd")
local C = ffi.C local C = ffi.C
require("ffi/posix_h")
local function readFile(file, bytes) local function readFile(file, bytes)
local f, str, err local f, str, err
@ -92,6 +94,8 @@ local codecs = {
C.free(cbuff) C.free(cbuff)
return nil, "failed to write file" return nil, "failed to write file"
end end
C.fflush(f)
C.fsync(C.fileno(f))
C.fclose(f) C.fclose(f)
C.free(cbuff) C.free(cbuff)
@ -232,21 +236,21 @@ function Persist:load()
if not t then if not t then
return nil, err return nil, err
end end
self.loaded = true
return t return t
end end
function Persist:save(t, as_bytecode) function Persist:save(t, as_bytecode)
local ok, err
if codecs[self.codec].writes_to_file then if codecs[self.codec].writes_to_file then
local ok, err = codecs[self.codec].serialize(t, as_bytecode, self.path) ok, err = codecs[self.codec].serialize(t, as_bytecode, self.path)
if not ok then if not ok then
return nil, err return nil, err
end end
-- c.f., note above, err is the on-disk size
return true, err
else else
local str, err = codecs[self.codec].serialize(t, as_bytecode) ok, err = codecs[self.codec].serialize(t, as_bytecode)
if not str then if not ok then
return nil, err return nil, err
end end
local file local file
@ -254,10 +258,19 @@ function Persist:save(t, as_bytecode)
if not file then if not file then
return nil, err return nil, err
end end
file:write(str) file:write(ok)
ffiUtil.fsyncOpenedFile(file)
file:close() file:close()
end end
return true
-- If we've just created the file, fsync the directory, too
if not self.loaded then
ffiUtil.fsyncDirectory(self.path)
self.loaded = true
end
-- c.f., note above, err is the on-disk size when writes_to_file is supported
return true, err
end end
function Persist:delete() function Persist:delete()

Loading…
Cancel
Save