s3:registry avoid updating keys which are going to be deleted in
authorGregor Beck <gbeck@sernet.de>
Mon, 1 Aug 2011 13:27:46 +0000 (15:27 +0200)
committerMichael Adam <obnox@samba.org>
Mon, 8 Aug 2011 13:27:07 +0000 (15:27 +0200)
reg_deletekey_recursive

this changes the complexity from O(n^2) to O(n) and reduces the time of
a 'net conf drop' with 10000 shares from 6min to 1.5s

Signed-off-by: Michael Adam <obnox@samba.org>
source3/include/registry.h
source3/registry/reg_api.c
source3/registry/reg_backend_db.c
source3/registry/reg_backend_smbconf.c
source3/registry/reg_dispatcher.c
source3/registry/reg_dispatcher.h

index c87b89af7bd0c7376dbfdfaaf25e3455dde69d49..f7a537ed0be79a1af9aa6d71ccfc131cdcfe0b12 100644 (file)
@@ -45,7 +45,7 @@ struct registry_ops {
        int     (*fetch_values) ( const char *key, struct regval_ctr *val );
        bool    (*store_subkeys)( const char *key, struct regsubkey_ctr *subkeys );
        WERROR  (*create_subkey)(const char *key, const char *subkey);
-       WERROR  (*delete_subkey)(const char *key, const char *subkey);
+       WERROR  (*delete_subkey)(const char *key, const char *subkey, bool lazy);
        bool    (*store_values)( const char *key, struct regval_ctr *val );
        bool    (*reg_access_check)( const char *keyname, uint32 requested,
                                     uint32 *granted,
index c66a95e406e6ca46cd3e7568a94c7000dfd97cd8..289f77df76bf8727ac650eb2dde6b4ff1227be49 100644 (file)
@@ -606,41 +606,29 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
        return err;
 }
 
-WERROR reg_deletekey(struct registry_key *parent, const char *path)
+static WERROR reg_deletekey_internal(TALLOC_CTX *mem_ctx,
+                                    struct registry_key *parent,
+                                    const char *path, bool lazy)
 {
        WERROR err;
        char *name, *end;
-       struct registry_key *tmp_key, *key;
-       TALLOC_CTX *mem_ctx = talloc_stackframe();
-
+       struct registry_key *key;
        name = talloc_strdup(mem_ctx, path);
        if (name == NULL) {
                err = WERR_NOMEM;
                goto done;
        }
 
-       /* check if the key has subkeys */
-       err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key);
-       W_ERROR_NOT_OK_GOTO_DONE(err);
-
-       err = fill_subkey_cache(key);
-       W_ERROR_NOT_OK_GOTO_DONE(err);
-
-       if (regsubkey_ctr_numkeys(key->subkeys) > 0) {
-               err = WERR_ACCESS_DENIED;
-               goto done;
-       }
-
        /* no subkeys - proceed with delete */
        end = strrchr(name, '\\');
        if (end != NULL) {
                *end = '\0';
 
                err = reg_openkey(mem_ctx, parent, name,
-                                 KEY_CREATE_SUB_KEY, &tmp_key);
+                                 KEY_CREATE_SUB_KEY, &key);
                W_ERROR_NOT_OK_GOTO_DONE(err);
 
-               parent = tmp_key;
+               parent = key;
                name = end+1;
        }
 
@@ -649,13 +637,36 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path)
                goto done;
        }
 
-       err = delete_reg_subkey(parent->key, name);
+       err = delete_reg_subkey(parent->key, name, lazy);
+
+done:
+       return err;
+}
+
+WERROR reg_deletekey(struct registry_key *parent, const char *path)
+{
+       WERROR err;
+       struct registry_key *key;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       /* check if the key has subkeys */
+       err = reg_openkey(mem_ctx, parent, path, REG_KEY_READ, &key);
+       W_ERROR_NOT_OK_GOTO_DONE(err);
+
+       err = fill_subkey_cache(key);
+       W_ERROR_NOT_OK_GOTO_DONE(err);
 
+       if (regsubkey_ctr_numkeys(key->subkeys) > 0) {
+               err = WERR_ACCESS_DENIED;
+               goto done;
+       }
+       err = reg_deletekey_internal(mem_ctx, parent, path, false);
 done:
        TALLOC_FREE(mem_ctx);
        return err;
 }
 
+
 WERROR reg_setvalue(struct registry_key *key, const char *name,
                    const struct registry_value *val)
 {
@@ -796,7 +807,7 @@ WERROR reg_deleteallvalues(struct registry_key *key)
  */
 static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
                                               const char *path,
-                                              bool del_key)
+                                              bool del_key, bool lazy)
 {
        WERROR werr = WERR_OK;
        struct registry_key *key;
@@ -819,13 +830,13 @@ static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
         */
        for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) {
                subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1);
-               werr = reg_deletekey_recursive_internal(key, subkey_name, true);
+               werr = reg_deletekey_recursive_internal(key, subkey_name, true, del_key);
                W_ERROR_NOT_OK_GOTO_DONE(werr);
        }
 
        if (del_key) {
                /* now delete the actual key */
-               werr = reg_deletekey(parent, path);
+               werr = reg_deletekey_internal(mem_ctx, parent, path, lazy);
        }
 
 done:
@@ -847,7 +858,7 @@ static WERROR reg_deletekey_recursive_trans(struct registry_key *parent,
                return werr;
        }
 
-       werr = reg_deletekey_recursive_internal(parent, path, del_key);
+       werr = reg_deletekey_recursive_internal(parent, path, del_key, false);
 
        if (!W_ERROR_IS_OK(werr)) {
                WERROR werr2;
index 62d482069c8bd6db450112896be202b422a0e0a2..57d6d3980c9fc3d61d8d43bb3136fd74f8eb7634 100644 (file)
@@ -1287,6 +1287,7 @@ struct regdb_delete_subkey_context {
        const char *key;
        const char *subkey;
        const char *path;
+       bool lazy;
 };
 
 static NTSTATUS regdb_delete_subkey_action(struct db_context *db,
@@ -1302,6 +1303,10 @@ static NTSTATUS regdb_delete_subkey_action(struct db_context *db,
        werr = regdb_delete_key_lists(db, delete_ctx->path);
        W_ERROR_NOT_OK_GOTO_DONE(werr);
 
+       if (delete_ctx->lazy) {
+               goto done;
+       }
+
        werr = regsubkey_ctr_init(mem_ctx, &subkeys);
        W_ERROR_NOT_OK_GOTO_DONE(werr);
 
@@ -1323,7 +1328,7 @@ done:
        return werror_to_ntstatus(werr);
 }
 
-static WERROR regdb_delete_subkey(const char *key, const char *subkey)
+static WERROR regdb_delete_subkey(const char *key, const char *subkey, bool lazy)
 {
        WERROR werr;
        char *path;
@@ -1349,6 +1354,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey)
        delete_ctx.key = key;
        delete_ctx.subkey = subkey;
        delete_ctx.path = path;
+       delete_ctx.lazy = lazy;
 
        werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
                                                  regdb_delete_subkey_action,
index 912f5eb1bf636af70fd38412cf67ac680e69ca99..11abb9cc6660e747b425eeadfa58c54fa104ed0c 100644 (file)
@@ -42,9 +42,9 @@ static WERROR smbconf_create_subkey(const char *key, const char *subkey)
        return regdb_ops.create_subkey(key, subkey);
 }
 
-static WERROR smbconf_delete_subkey(const char *key, const char *subkey)
+static WERROR smbconf_delete_subkey(const char *key, const char *subkey, bool lazy)
 {
-       return regdb_ops.delete_subkey(key, subkey);
+       return regdb_ops.delete_subkey(key, subkey, lazy);
 }
 
 static int smbconf_fetch_values(const char *key, struct regval_ctr *val)
index a96047817d9a033f5704a285d5daf93edfd0c43a..5b52e98e08cd5653baf4e9a215db9a050f901ac7 100644 (file)
@@ -113,10 +113,10 @@ WERROR create_reg_subkey(struct registry_key_handle *key, const char *subkey)
        return WERR_NOT_SUPPORTED;
 }
 
-WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey)
+WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey, bool lazy)
 {
        if (key->ops && key->ops->delete_subkey) {
-               return key->ops->delete_subkey(key->name, subkey);
+               return key->ops->delete_subkey(key->name, subkey, lazy);
        }
 
        return WERR_NOT_SUPPORTED;
index c80ba15ec1dfd08873e7cda07dcad4c9679fa1be..ec4474629c3385c199ade67c5f5ef3ac5d53a85c 100644 (file)
@@ -25,7 +25,7 @@ bool store_reg_keys(struct registry_key_handle *key,
                    struct regsubkey_ctr *subkeys);
 bool store_reg_values(struct registry_key_handle *key, struct regval_ctr *val);
 WERROR create_reg_subkey(struct registry_key_handle *key, const char *subkey);
-WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey);
+WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey, bool lazy);
 int fetch_reg_keys(struct registry_key_handle *key,
                   struct regsubkey_ctr *subkey_ctr);
 int fetch_reg_values(struct registry_key_handle *key, struct regval_ctr *val);