Software /
code /
prosody
Comparison
util/datamanager.lua @ 5045:4ba6940deed0
util.datamanager: Use pposix.fallocate() to make sure appends succeed. Also add a fallback fallocate()
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 28 Jul 2012 22:37:24 +0200 |
parent | 5038:242c62ff8e77 |
child | 5049:5d685f123332 |
comparison
equal
deleted
inserted
replaced
5044:4ef0dbfead53 | 5045:4ba6940deed0 |
---|---|
19 local error = error; | 19 local error = error; |
20 local next = next; | 20 local next = next; |
21 local t_insert = table.insert; | 21 local t_insert = table.insert; |
22 local append = require "util.serialization".append; | 22 local append = require "util.serialization".append; |
23 local envloadfile = require"util.envload".envloadfile; | 23 local envloadfile = require"util.envload".envloadfile; |
24 local serialize = require "util.serialization".serialize; | |
24 local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) -- Extract directory seperator from package.config (an undocumented string that comes with lua) | 25 local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) -- Extract directory seperator from package.config (an undocumented string that comes with lua) |
25 local lfs = require "lfs"; | 26 local lfs = require "lfs"; |
26 local prosody = prosody; | 27 local prosody = prosody; |
27 local raw_mkdir; | 28 local raw_mkdir; |
29 local fallocate; | |
28 | 30 |
29 if prosody.platform == "posix" then | 31 if prosody.platform == "posix" then |
30 raw_mkdir = require "util.pposix".mkdir; -- Doesn't trample on umask | 32 raw_mkdir = require "util.pposix".mkdir; -- Doesn't trample on umask |
33 fallocate = require "util.pposix".fallocate; | |
31 else | 34 else |
32 raw_mkdir = lfs.mkdir; | 35 raw_mkdir = lfs.mkdir; |
36 end | |
37 | |
38 if not fallocate then -- Fallback | |
39 function fallocate(f, offset, len) | |
40 -- This assumes that current position == offset | |
41 local fake_data = (" "):rep(len); | |
42 local ok, msg = f:write(fake_data); | |
43 if not ok then | |
44 return ok, msg; | |
45 end | |
46 f:seek(offset); | |
47 return true; | |
48 end | |
33 end | 49 end |
34 | 50 |
35 module "datamanager" | 51 module "datamanager" |
36 | 52 |
37 ---- utils ----- | 53 ---- utils ----- |
163 | 179 |
164 function list_append(username, host, datastore, data) | 180 function list_append(username, host, datastore, data) |
165 if not data then return; end | 181 if not data then return; end |
166 if callback(username, host, datastore) == false then return true; end | 182 if callback(username, host, datastore) == false then return true; end |
167 -- save the datastore | 183 -- save the datastore |
168 local f, msg = io_open(getpath(username, host, datastore, "list", true), "a+"); | 184 local f, msg = io_open(getpath(username, host, datastore, "list", true), "a"); |
169 if not f then | 185 if not f then |
170 log("error", "Unable to write to %s storage ('%s') for user: %s@%s", datastore, msg, username or "nil", host or "nil"); | 186 log("error", "Unable to write to %s storage ('%s') for user: %s@%s", datastore, msg, username or "nil", host or "nil"); |
171 return; | 187 return; |
172 end | 188 end |
173 f:write("item("); | 189 local data = "item(" .. serialize(data) .. ");\n"; |
174 append(f, data); | 190 local pos = f:seek("end"); |
175 f:write(");\n"); | 191 local ok, msg = fallocate(f, pos, #data); |
192 f:seek("set", pos); | |
193 if ok then | |
194 f:write(data); | |
195 else | |
196 log("error", "Unable to write to %s storage ('%s') for user: %s@%s", datastore, msg, username or "nil", host or "nil"); | |
197 return ok, msg; | |
198 end | |
176 f:close(); | 199 f:close(); |
177 return true; | 200 return true; |
178 end | 201 end |
179 | 202 |
180 function list_store(username, host, datastore, data) | 203 function list_store(username, host, datastore, data) |