summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-04-30 13:49:25 +0100
committerVincent Sanders <vince@kyllikki.org>2015-04-30 13:49:25 +0100
commit05538c0264db8ba117248f481e769f62969dc82b (patch)
tree09819251607b3ece5913be283256e9505c3c97b8
parentc6a6c8e7faa9165d5337e61c6bd331071367cec0 (diff)
downloadnetsurf-05538c0264db8ba117248f481e769f62969dc82b.tar.gz
netsurf-05538c0264db8ba117248f481e769f62969dc82b.tar.bz2
Ensure small block cache files allocate their entire extent at open.
It seems many filesystems are greatly more efficient if the block file is allocated its entire extent once rather than trying to continuously grown the file later. The size of the block files is known at their creation time so this change ensures they are grown to the full possible extent hence removing future inefficient writes.
-rw-r--r--content/fs_backing_store.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/content/fs_backing_store.c b/content/fs_backing_store.c
index d23a9d1bc..2a5b3ea77 100644
--- a/content/fs_backing_store.c
+++ b/content/fs_backing_store.c
@@ -31,8 +31,6 @@
* lifetime is typically very short, though this may be obsoleted
* by a small object storage stratagy.
*
- * \todo make backing store have a more efficient small object storage.
- *
*/
#include <unistd.h>
@@ -1591,9 +1589,14 @@ static nserror store_write_block(struct store_state *state,
if (state->blocks[elem_idx][bf].fd == -1) {
state->blocks[elem_idx][bf].fd = store_open(state, bf,
elem_idx + ENTRY_ELEM_COUNT, O_CREAT | O_RDWR);
- }
- if (state->blocks[elem_idx][bf].fd == -1) {
- return NSERROR_SAVE_FAILED;
+ if (state->blocks[elem_idx][bf].fd == -1) {
+ LOG(("Open failed errno %d", errno));
+ return NSERROR_SAVE_FAILED;
+ }
+
+ /* ensure block file is correct length at open */
+ ftruncate(state->blocks[elem_idx][bf].fd,
+ 1U << (log2_block_size[elem_idx] + BLOCK_ENTRY_COUNT));
}
offst = bi << log2_block_size[elem_idx];
@@ -1745,11 +1748,16 @@ static nserror store_read_block(struct store_state *state,
/* ensure the block file fd is good */
if (state->blocks[elem_idx][bf].fd == -1) {
- state->blocks[elem_idx][bf].fd = store_open(state, bf, elem_idx + ENTRY_ELEM_COUNT, O_CREAT | O_RDWR);
- }
- if (state->blocks[elem_idx][bf].fd == -1) {
- LOG(("Open failed errno %d", errno));
- return NSERROR_SAVE_FAILED;
+ state->blocks[elem_idx][bf].fd = store_open(state, bf,
+ elem_idx + ENTRY_ELEM_COUNT, O_CREAT | O_RDWR);
+ if (state->blocks[elem_idx][bf].fd == -1) {
+ LOG(("Open failed errno %d", errno));
+ return NSERROR_SAVE_FAILED;
+ }
+
+ /* ensure block file is correct length at open */
+ ftruncate(state->blocks[elem_idx][bf].fd,
+ 1U << (log2_block_size[elem_idx] + BLOCK_ENTRY_COUNT));
}
offst = bi << log2_block_size[elem_idx];