Mercurial > prosody-hg
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 |
| parents | 242c62ff8e77 |
| children | 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) |
