From 232666b12f1a6d17ba65b5ef36656ab9bb62f42f Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Wed, 9 Nov 2011 01:03:14 -0800
Subject: [PATCH] Key alignment tweaks for Sparc

---
 servers/slapd/back-mdb/back-mdb.h |  4 ++++
 servers/slapd/back-mdb/idl.c      | 40 +++++++++++++++++++++++++++----
 servers/slapd/back-mdb/index.c    |  2 +-
 servers/slapd/back-mdb/key.c      | 17 +++++++++++--
 4 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/servers/slapd/back-mdb/back-mdb.h b/servers/slapd/back-mdb/back-mdb.h
index 603812830b..d0377a3e05 100644
--- a/servers/slapd/back-mdb/back-mdb.h
+++ b/servers/slapd/back-mdb/back-mdb.h
@@ -168,6 +168,10 @@ typedef struct AttrList {
 #define CACHELINE	64
 #endif
 
+#if defined(__i386) || defined(__x86_64)
+#define MISALIGNED_OK	1
+#endif
+
 typedef struct IndexRbody {
 	AttrInfo *ai;
 	AttrList *attrs;
diff --git a/servers/slapd/back-mdb/idl.c b/servers/slapd/back-mdb/idl.c
index f4cb11f960..1bc048a3b6 100644
--- a/servers/slapd/back-mdb/idl.c
+++ b/servers/slapd/back-mdb/idl.c
@@ -400,6 +400,9 @@ mdb_idl_insert_keys(
 	char *err;
 	int	rc, k;
 	unsigned int flag = MDB_NODUPDATA;
+#ifndef	MISALIGNED_OK
+	int kbuf[2];
+#endif
 
 	{
 		char buf[16];
@@ -413,12 +416,25 @@ mdb_idl_insert_keys(
 	if ( slapMode & SLAP_TOOL_QUICK )
 		flag |= MDB_APPEND;
 
+#ifndef MISALIGNED_OK
+	if (keys[0].bv_len & 0x03)
+		kbuf[1] = 0;
+#endif
 	for ( k=0; keys[k].bv_val; k++ ) {
 	/* Fetch the first data item for this key, to see if it
 	 * exists and if it's a range.
 	 */
-	key.mv_size = keys[k].bv_len;
-	key.mv_data = keys[k].bv_val;
+#ifndef MISALIGNED_OK
+	if (keys[k].bv_len & 0x03) {
+		key.mv_size = sizeof(kbuf);
+		key.mv_data = kbuf;
+		memcpy(key.mv_data, keys[k].bv_val, keys[k].bv_len);
+	} else
+#endif
+	{
+		key.mv_size = keys[k].bv_len;
+		key.mv_data = keys[k].bv_val;
+	}
 	rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
 	err = "c_get";
 	if ( rc == 0 ) {
@@ -534,6 +550,9 @@ mdb_idl_delete_keys(
 	MDB_val key, data;
 	ID lo, hi, tmp, *i;
 	char *err;
+#ifndef	MISALIGNED_OK
+	int kbuf[2];
+#endif
 
 	{
 		char buf[16];
@@ -543,12 +562,25 @@ mdb_idl_delete_keys(
 	}
 	assert( id != NOID );
 
+#ifndef MISALIGNED_OK
+	if (keys[0].bv_len & 0x03)
+		kbuf[1] = 0;
+#endif
 	for ( k=0; keys[k].bv_val; k++) {
 	/* Fetch the first data item for this key, to see if it
 	 * exists and if it's a range.
 	 */
-	key.mv_size = keys[k].bv_len;
-	key.mv_data = keys[k].bv_val;
+#ifndef MISALIGNED_OK
+	if (keys[k].bv_len & 0x03) {
+		key.mv_size = sizeof(kbuf);
+		key.mv_data = kbuf;
+		memcpy(key.mv_data, keys[k].bv_val, keys[k].bv_len);
+	} else
+#endif
+	{
+		key.mv_size = keys[k].bv_len;
+		key.mv_data = keys[k].bv_val;
+	}
 	rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
 	err = "c_get";
 	if ( rc == 0 ) {
diff --git a/servers/slapd/back-mdb/index.c b/servers/slapd/back-mdb/index.c
index 2b71bc1a2a..4d2dc01457 100644
--- a/servers/slapd/back-mdb/index.c
+++ b/servers/slapd/back-mdb/index.c
@@ -25,7 +25,7 @@
 #include "back-mdb.h"
 #include "lutil_hash.h"
 
-static char presence_keyval[] = {0,0};
+static char presence_keyval[] = {0,0,0,0,0};
 static struct berval presence_key[2] = {BER_BVC(presence_keyval), BER_BVNULL};
 
 AttrInfo *mdb_index_mask(
diff --git a/servers/slapd/back-mdb/key.c b/servers/slapd/back-mdb/key.c
index 45af1cd1f4..a147cfa5c5 100644
--- a/servers/slapd/back-mdb/key.c
+++ b/servers/slapd/back-mdb/key.c
@@ -39,11 +39,24 @@ mdb_key_read(
 {
 	int rc;
 	MDB_val key;
+#ifndef MSIALIGNED_OK
+	int kbuf[2];
+#endif
 
 	Debug( LDAP_DEBUG_TRACE, "=> key_read\n", 0, 0, 0 );
 
-	key.mv_size = k->bv_len;
-	key.mv_data = k->bv_val;
+#ifndef MISALIGNED_OK
+	if (k->bv_len & 0x03) {
+		key.mv_size = sizeof(kbuf);
+		key.mv_data = kbuf;
+		kbuf[1] = 0;
+		memcpy(kbuf, k->bv_val, k->bv_len);
+	} else
+#endif
+	{
+		key.mv_size = k->bv_len;
+		key.mv_data = k->bv_val;
+	}
 
 	rc = mdb_idl_fetch_key( be, txn, dbi, &key, ids, saved_cursor, get_flag );
 
-- 
GitLab