summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorWilco Baan Hofman <wilco@baanhofman.nl>2010-07-27 11:13:24 +0200
committerJelmer Vernooij <jelmer@samba.org>2010-10-03 15:31:37 +0200
commita23aa3f5f150d06c1943e5031a239d58ef7b068c (patch)
tree56f4461e807cc0b3c00031ca40d170214ca5bb86 /source4
parent927e4db0909b54dd94df51d92266ba8dbe09e214 (diff)
downloadsamba-a23aa3f5f150d06c1943e5031a239d58ef7b068c.tar.gz
samba-a23aa3f5f150d06c1943e5031a239d58ef7b068c.tar.bz2
samba-a23aa3f5f150d06c1943e5031a239d58ef7b068c.zip
Make sure that regf only writes to disk every five seconds or when flushed or destroyed
Brings speed up on a large .reg import from 17.5s to 0.95s, over 18 times faster Signed-off-by: Jelmer Vernooij <jelmer@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/registry/regf.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c
index b62109ed57..f377099ea1 100644
--- a/source4/lib/registry/regf.c
+++ b/source4/lib/registry/regf.c
@@ -2,7 +2,7 @@
Samba CIFS implementation
Registry backend for REGF files
Copyright (C) 2005-2007 Jelmer Vernooij, jelmer@samba.org
- Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl
+ Copyright (C) 2006-2010 Wilco Baan Hofman, wilco@baanhofman.nl
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -49,9 +49,10 @@ struct regf_data {
int fd;
struct hbin_block **hbins;
struct regf_hdr *header;
+ time_t last_write;
};
-static WERROR regf_save_hbin(struct regf_data *data);
+static WERROR regf_save_hbin(struct regf_data *data, int flush);
struct regf_key_data {
struct hive_key key;
@@ -1621,7 +1622,7 @@ static WERROR regf_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block,
private_data->offset, nk);
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
@@ -1720,7 +1721,7 @@ static WERROR regf_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
}
hbin_free(private_data->hive, key->offset);
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,
@@ -1784,7 +1785,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,
*ret = (struct hive_key *)regf_get_key(ctx, regf, offset);
DEBUG(9, ("Storing key %s\n", name));
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
static WERROR regf_set_value(struct hive_key *key, const char *name,
@@ -1903,16 +1904,23 @@ static WERROR regf_set_value(struct hive_key *key, const char *name,
hbin_store_tdr_resize(regf,
(tdr_push_fn_t) tdr_push_nk_block,
private_data->offset, nk);
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
-static WERROR regf_save_hbin(struct regf_data *regf)
+static WERROR regf_save_hbin(struct regf_data *regf, int flush)
{
struct tdr_push *push = tdr_push_init(regf);
unsigned int i;
W_ERROR_HAVE_NO_MEMORY(push);
+ /* Only write once every 5 seconds, or when flush is set */
+ if (!flush && regf->last_write + 5 >= time(NULL)) {
+ return WERR_OK;
+ }
+
+ regf->last_write = time(NULL);
+
if (lseek(regf->fd, 0, SEEK_SET) == -1) {
DEBUG(0, ("Error lseeking in regf file\n"));
return WERR_GENERAL_FAILURE;
@@ -2064,7 +2072,7 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
*key = (struct hive_key *)regf_get_key(parent_ctx, regf,
regf->header->data_offset);
- error = regf_save_hbin(regf);
+ error = regf_save_hbin(regf, 1);
if (!W_ERROR_IS_OK(error)) {
return error;
}
@@ -2075,6 +2083,38 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
return WERR_OK;
}
+static WERROR regf_flush_key(struct hive_key *key)
+{
+ struct regf_key_data *private_data = (struct regf_key_data *)key;
+ struct regf_data *regf = private_data->hive;
+ WERROR error;
+
+ error = regf_save_hbin(regf, 1);
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(0, ("Failed to flush regf to disk\n"));
+ return error;
+ }
+
+ return WERR_OK;
+}
+
+static int regf_destruct(struct regf_data *regf)
+{
+ WERROR error;
+
+ /* Write to disk */
+ error = regf_save_hbin(regf, 1);
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(0, ("Failed to flush registry to disk\n"));
+ return -1;
+ }
+
+ /* Close file descriptor */
+ close(regf->fd);
+
+ return 0;
+}
+
WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
struct hive_key **key)
{
@@ -2084,9 +2124,10 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
unsigned int i;
regf = (struct regf_data *)talloc_zero(parent_ctx, struct regf_data);
-
W_ERROR_HAVE_NO_MEMORY(regf);
+ talloc_set_destructor(regf, regf_destruct);
+
DEBUG(5, ("Attempting to load registry file\n"));
/* Get the header */
@@ -2197,4 +2238,5 @@ static struct hive_operations reg_backend_regf = {
.set_value = regf_set_value,
.del_key = regf_del_key,
.delete_value = regf_del_value,
+ .flush_key = regf_flush_key
};