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)