dbwrap: Remove talloc from dbwrap_watch_record_stored()
authorVolker Lendecke <vl@samba.org>
Sun, 20 Sep 2015 16:25:20 +0000 (18:25 +0200)
committerRalph Böhme <slow@samba.org>
Tue, 22 Sep 2015 05:50:57 +0000 (07:50 +0200)
This happens on every store to locking.tdb for example, so we should
make it cheap.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Tue Sep 22 07:50:58 CEST 2015 on sn-devel-104

source3/lib/dbwrap/dbwrap_watch.c

index 1540e0ba8b70263b559d53b8cc14f456d7442ef4..426fe77e4384692ac593347d2c0baf5c50abd944 100644 (file)
@@ -193,44 +193,6 @@ done:
        return status;
 }
 
-static NTSTATUS dbwrap_record_get_watchers(struct db_context *db,
-                                          struct db_record *rec,
-                                          TALLOC_CTX *mem_ctx,
-                                          struct server_id **p_ids,
-                                          size_t *p_num_ids)
-{
-       struct db_context *w_db;
-       size_t wkey_len = dbwrap_record_watchers_key(db, rec, NULL, 0);
-       uint8_t wkey_buf[wkey_len];
-       TDB_DATA wkey = { .dptr = wkey_buf, .dsize = wkey_len };
-       TDB_DATA value = { 0, };
-       struct server_id *ids;
-       NTSTATUS status;
-
-       dbwrap_record_watchers_key(db, rec, wkey_buf, wkey_len);
-
-       w_db = dbwrap_record_watchers_db();
-       if (w_db == NULL) {
-               status = NT_STATUS_INTERNAL_ERROR;
-               goto fail;
-       }
-       status = dbwrap_fetch(w_db, mem_ctx, wkey, &value);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto fail;
-       }
-       if ((value.dsize % sizeof(struct server_id)) != 0) {
-               status = NT_STATUS_INTERNAL_DB_CORRUPTION;
-               goto fail;
-       }
-       ids = (struct server_id *)value.dptr;
-       *p_ids = talloc_move(mem_ctx, &ids);
-       *p_num_ids = value.dsize / sizeof(struct server_id);
-       return NT_STATUS_OK;
-fail:
-       TALLOC_FREE(value.dptr);
-       return status;
-}
-
 struct dbwrap_record_watch_state {
        struct tevent_context *ev;
        struct db_context *db;
@@ -326,48 +288,67 @@ static int dbwrap_record_watch_state_destructor(
        return 0;
 }
 
+static void dbwrap_watch_record_stored_fn(TDB_DATA key, TDB_DATA data,
+                                         void *private_data)
+{
+       struct messaging_context *msg = private_data;
+       size_t i, num_ids;
+
+       if ((data.dsize % sizeof(struct server_id)) != 0) {
+               DBG_WARNING("%s: Invalid data size: %zu\n", __func__,
+                           data.dsize);
+               return;
+       }
+       num_ids = data.dsize / sizeof(struct server_id);
+
+       for (i=0; i<num_ids; i++) {
+               struct server_id dst;
+               NTSTATUS status;
+
+               memcpy(&dst, data.dptr + i * sizeof(struct server_id),
+                      sizeof(struct server_id));
+
+               status = messaging_send_buf(msg, dst, MSG_DBWRAP_MODIFIED,
+                                           key.dptr, key.dsize);
+               if (!NT_STATUS_IS_OK(status)) {
+                       struct server_id_buf tmp;
+                       DBG_WARNING("%s: messaging_send to %s failed: %s\n",
+                                   __func__, server_id_str_buf(dst, &tmp),
+                                   nt_errstr(status));
+               }
+       }
+}
+
 static void dbwrap_watch_record_stored(struct db_context *db,
                                       struct db_record *rec,
                                       void *private_data)
 {
        struct messaging_context *msg = talloc_get_type_abort(
                private_data, struct messaging_context);
-       struct server_id *ids = NULL;
-       size_t num_ids = 0;
+       struct db_context *watchers_db;
 
        size_t wkey_len = dbwrap_record_watchers_key(db, rec, NULL, 0);
        uint8_t wkey_buf[wkey_len];
        TDB_DATA wkey = { .dptr = wkey_buf, .dsize = wkey_len };
 
        NTSTATUS status;
-       uint32_t i;
+
+       watchers_db = dbwrap_record_watchers_db();
+       if (watchers_db == NULL) {
+               return;
+       }
 
        dbwrap_record_watchers_key(db, rec, wkey_buf, wkey_len);
 
-       status = dbwrap_record_get_watchers(db, rec, talloc_tos(),
-                                           &ids, &num_ids);
+       status = dbwrap_parse_record(watchers_db, wkey,
+                                    dbwrap_watch_record_stored_fn, msg);
        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-               goto done;
+               return;
        }
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("dbwrap_record_get_watchers failed: %s\n",
-                         nt_errstr(status)));
-               goto done;
+               DBG_WARNING("%s: dbwrap_parse_record failed: %s\n",
+                           __func__, nt_errstr(status));
        }
-
-       for (i=0; i<num_ids; i++) {
-               status = messaging_send_buf(msg, ids[i], MSG_DBWRAP_MODIFIED,
-                                           wkey.dptr, wkey.dsize);
-               if (!NT_STATUS_IS_OK(status)) {
-                       struct server_id_buf tmp;
-                       DEBUG(1, ("messaging_send to %s failed: %s\n",
-                                 server_id_str_buf(ids[i], &tmp),
-                                 nt_errstr(status)));
-               }
-       }
-done:
-       TALLOC_FREE(ids);
-       return;
 }
 
 void dbwrap_watch_db(struct db_context *db, struct messaging_context *msg)