summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2016-07-27 00:17:36 +1200
committerStefan Metzmacher <metze@samba.org>2016-07-28 10:06:12 +0200
commitf6e87188b60bea7d15bc015a8617e7ed3f7fbeda (patch)
tree891d28d73260e2da86f34c53997b7bfc79e641eb /lib
parentebdf6e079b758aeb750201c4989706c43af2420e (diff)
downloadsamba-f6e87188b60bea7d15bc015a8617e7ed3f7fbeda.tar.gz
ldb: Add ldb_unpack_data_only_attr_list_flags()
This function allows us to control allocation of memory during parse of the packed ldb data. This in turn can have an important performance impact as each small allocation can have a large overhead Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Diffstat (limited to 'lib')
-rw-r--r--lib/ldb/ABI/ldb-1.1.26.sigs1
-rw-r--r--lib/ldb/common/ldb_pack.c83
-rw-r--r--lib/ldb/include/ldb_module.h28
3 files changed, 88 insertions, 24 deletions
diff --git a/lib/ldb/ABI/ldb-1.1.26.sigs b/lib/ldb/ABI/ldb-1.1.26.sigs
index 3f33df96f74..4fa30d88ec9 100644
--- a/lib/ldb/ABI/ldb-1.1.26.sigs
+++ b/lib/ldb/ABI/ldb-1.1.26.sigs
@@ -254,6 +254,7 @@ ldb_transaction_prepare_commit: int (struct ldb_context *)
ldb_transaction_start: int (struct ldb_context *)
ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *)
ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *)
+ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *)
ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *)
ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *)
ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c
index 7970b9d3ecb..cc3a5527583 100644
--- a/lib/ldb/common/ldb_pack.c
+++ b/lib/ldb/common/ldb_pack.c
@@ -211,20 +211,20 @@ static bool ldb_consume_element_data(uint8_t **pp, size_t *premaining)
return true;
}
+
/*
* Unpack a ldb message from a linear buffer in ldb_val
*
* Providing a list of attributes to this function allows selective unpacking.
* Giving a NULL list (or a list_size of 0) unpacks all the attributes.
- *
- * Free with ldb_unpack_data_free()
*/
-int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
- const struct ldb_val *data,
- struct ldb_message *message,
- const char * const *list,
- unsigned int list_size,
- unsigned int *nb_elements_in_db)
+int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb,
+ const struct ldb_val *data,
+ struct ldb_message *message,
+ const char * const *list,
+ unsigned int list_size,
+ unsigned int flags,
+ unsigned int *nb_elements_in_db)
{
uint8_t *p;
size_t remaining;
@@ -271,10 +271,14 @@ int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
errno = EIO;
goto failed;
}
- message->dn = ldb_dn_new(message, ldb, (char *)p);
- if (message->dn == NULL) {
- errno = ENOMEM;
- goto failed;
+ if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) {
+ message->dn = NULL;
+ } else {
+ message->dn = ldb_dn_new(message, ldb, (char *)p);
+ if (message->dn == NULL) {
+ errno = ENOMEM;
+ goto failed;
+ }
}
/*
* Redundant: by definition, remaining must be more
@@ -373,11 +377,15 @@ int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
}
}
element = &message->elements[nelem];
- element->name = talloc_memdup(message->elements, attr, attr_len+1);
+ if (flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
+ element->name = attr;
+ } else {
+ element->name = talloc_memdup(message->elements, attr, attr_len+1);
- if (element->name == NULL) {
- errno = ENOMEM;
- goto failed;
+ if (element->name == NULL) {
+ errno = ENOMEM;
+ goto failed;
+ }
}
element->flags = 0;
@@ -422,15 +430,18 @@ int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
}
element->values[j].length = len;
- element->values[j].data = talloc_size(element->values, len+1);
- if (element->values[j].data == NULL) {
- errno = ENOMEM;
- goto failed;
+ if (flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
+ element->values[j].data = p + 4;
+ } else {
+ element->values[j].data = talloc_size(element->values, len+1);
+ if (element->values[j].data == NULL) {
+ errno = ENOMEM;
+ goto failed;
+ }
+ memcpy(element->values[j].data, p + 4,
+ len);
+ element->values[j].data[len] = 0;
}
- memcpy(element->values[j].data, p + 4,
- len);
- element->values[j].data[len] = 0;
-
remaining -= len;
p += len+4+1;
}
@@ -463,6 +474,30 @@ failed:
return -1;
}
+/*
+ * Unpack a ldb message from a linear buffer in ldb_val
+ *
+ * Providing a list of attributes to this function allows selective unpacking.
+ * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
+ *
+ * Free with ldb_unpack_data_free()
+ */
+int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
+ const struct ldb_val *data,
+ struct ldb_message *message,
+ const char * const *list,
+ unsigned int list_size,
+ unsigned int *nb_elements_in_db)
+{
+ return ldb_unpack_data_only_attr_list_flags(ldb,
+ data,
+ message,
+ list,
+ list_size,
+ 0,
+ nb_elements_in_db);
+}
+
int ldb_unpack_data(struct ldb_context *ldb,
const struct ldb_val *data,
struct ldb_message *message)
diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h
index c6a24d35e53..1c48590a381 100644
--- a/lib/ldb/include/ldb_module.h
+++ b/lib/ldb/include/ldb_module.h
@@ -390,6 +390,12 @@ int ldb_register_extended_match_rule(struct ldb_context *ldb,
int ldb_pack_data(struct ldb_context *ldb,
const struct ldb_message *message,
struct ldb_val *data);
+/*
+ * Unpack a ldb message from a linear buffer in ldb_val
+ *
+ * Providing a list of attributes to this function allows selective unpacking.
+ * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
+ */
int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
const struct ldb_val *data,
struct ldb_message *message,
@@ -399,5 +405,27 @@ int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
int ldb_unpack_data(struct ldb_context *ldb,
const struct ldb_val *data,
struct ldb_message *message);
+/*
+ * Unpack a ldb message from a linear buffer in ldb_val
+ *
+ * Providing a list of attributes to this function allows selective unpacking.
+ * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
+ *
+ * Flags allow control of allocation, so that if
+ * LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC is specified, then values are
+ * not allocate, instead they point into the supplier constant buffer.
+ *
+ * Likewise if LDB_UNPACK_DATA_FLAG_NO_DN is specified, the DN is omitted.
+ */
+int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb,
+ const struct ldb_val *data,
+ struct ldb_message *message,
+ const char * const *list,
+ unsigned int list_size,
+ unsigned int flags,
+ unsigned int *nb_elements_in_db);
+
+#define LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC 0x0001
+#define LDB_UNPACK_DATA_FLAG_NO_DN 0x0002
#endif