aboutsummaryrefslogtreecommitdiffstats
path: root/util/datamanager.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/datamanager.lua')
-rw-r--r--util/datamanager.lua40
1 files changed, 17 insertions, 23 deletions
diff --git a/util/datamanager.lua b/util/datamanager.lua
index b825cb33..b2a5fa0e 100644
--- a/util/datamanager.lua
+++ b/util/datamanager.lua
@@ -17,7 +17,6 @@ local io_open = io.open;
local os_remove = os.remove;
local os_rename = os.rename;
local tonumber = tonumber;
-local tostring = tostring;
local next = next;
local type = type;
local t_insert = table.insert;
@@ -31,21 +30,12 @@ local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.
local prosody = prosody;
local raw_mkdir = lfs.mkdir;
-local function fallocate(f, offset, len)
- -- This assumes that current position == offset
- local fake_data = (" "):rep(len);
- local ok, msg = f:write(fake_data);
- if not ok then
- return ok, msg;
- end
- f:seek("set", offset);
- return true;
-end;
+local atomic_append;
local ENOENT = 2;
pcall(function()
local pposix = require "util.pposix";
raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask
- fallocate = pposix.fallocate or fallocate;
+ atomic_append = pposix.atomic_append;
ENOENT = pposix.ENOENT or ENOENT;
end);
@@ -65,6 +55,19 @@ do
end
end
+if not atomic_append then
+ function atomic_append(f, data)
+ local pos = f:seek();
+ if not f:write(data) or not f:flush() then
+ f:seek("set", pos);
+ f:write((" "):rep(#data));
+ f:flush();
+ return nil, "write-failed";
+ end
+ return true;
+ end
+end
+
local _mkdir = {};
local function mkdir(path)
path = path:gsub("/", path_separator); -- TODO as an optimization, do this during path creation rather than here
@@ -221,25 +224,16 @@ local function append(username, host, datastore, ext, data)
local filename = getpath(username, host, datastore, ext, true);
local ok;
- local f, msg = io_open(filename, "r+");
+ local f, msg, errno = io_open(filename, "r+");
if not f then
return atomic_store(filename, data);
-- File did probably not exist, let's create it
end
local pos = f:seek("end");
- ok, msg = fallocate(f, pos, #data);
- if not ok then
- log("warn", "fallocate() failed: %s", tostring(msg));
- -- This doesn't work on every file system
- end
- if f:seek() ~= pos then
- log("debug", "fallocate() changed file position");
- f:seek("set", pos);
- end
+ ok, msg = atomic_append(f, data);
- ok, msg = f:write(data);
if not ok then
f:close();
return ok, msg, "write";