1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

ntdb: take advantage of direct access across expand.

This means we no longer have to unmap if we want to compare a record.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2012-06-22 09:44:41 +09:30
parent 4c51ee1116
commit 7c1d9fb3c1

View File

@ -68,8 +68,7 @@ static ntdb_bool_err match(struct ntdb_context *ntdb,
const NTDB_DATA *key, const NTDB_DATA *key,
ntdb_off_t val, ntdb_off_t val,
struct ntdb_used_record *rec, struct ntdb_used_record *rec,
const char **rptr, const char **rptr)
const ntdb_off_t **mapped)
{ {
ntdb_off_t off; ntdb_off_t off;
enum NTDB_ERROR ecode; enum NTDB_ERROR ecode;
@ -83,12 +82,6 @@ static ntdb_bool_err match(struct ntdb_context *ntdb,
return false; return false;
} }
/* Unmap before we try to read actual record, which may cause expand */
if (mapped) {
ntdb_access_release(ntdb, *mapped);
*mapped = NULL;
}
off = val & NTDB_OFF_MASK; off = val & NTDB_OFF_MASK;
ecode = ntdb_read_convert(ntdb, off, rec, sizeof(*rec)); ecode = ntdb_read_convert(ntdb, off, rec, sizeof(*rec));
if (ecode != NTDB_SUCCESS) { if (ecode != NTDB_SUCCESS) {
@ -151,7 +144,7 @@ ntdb_off_t find_and_lock(struct ntdb_context *ntdb,
/* Directly in hash table? */ /* Directly in hash table? */
if (!likely(is_chain(val))) { if (!likely(is_chain(val))) {
if (val) { if (val) {
berr = match(ntdb, h->h, &key, val, rec, rptr, NULL); berr = match(ntdb, h->h, &key, val, rec, rptr);
if (berr < 0) { if (berr < 0) {
ecode = NTDB_OFF_TO_ERR(berr); ecode = NTDB_OFF_TO_ERR(berr);
goto fail; goto fail;
@ -184,41 +177,32 @@ ntdb_off_t find_and_lock(struct ntdb_context *ntdb,
h->table_size = rec_data_length(&chdr) / sizeof(ntdb_off_t); h->table_size = rec_data_length(&chdr) / sizeof(ntdb_off_t);
arr = ntdb_access_read(ntdb, hbucket_off(h->table, 0),
rec_data_length(&chdr), true);
if (NTDB_PTR_IS_ERR(arr)) {
ecode = NTDB_PTR_ERR(arr);
goto fail;
}
found_empty = false; found_empty = false;
for (i = 0; i < h->table_size; i++) { for (i = 0; i < h->table_size; i++) {
/* Careful! match has to unmap this if we access a if (arr[i] == 0) {
* record (may cause mmap of database to move. */
if (!arr) {
arr = ntdb_access_read(ntdb, hbucket_off(h->table, 0),
rec_data_length(&chdr), true);
if (NTDB_PTR_IS_ERR(arr)) {
ecode = NTDB_PTR_ERR(arr);
goto fail;
}
}
val = arr[i];
if (val == 0) {
if (!found_empty) { if (!found_empty) {
h->bucket = i; h->bucket = i;
found_empty = true; found_empty = true;
} }
} else { } else {
berr = match(ntdb, h->h, &key, val, rec, rptr, &arr); berr = match(ntdb, h->h, &key, arr[i], rec, rptr);
if (berr < 0) { if (berr < 0) {
ecode = NTDB_OFF_TO_ERR(berr); ecode = NTDB_OFF_TO_ERR(berr);
if (arr) { ntdb_access_release(ntdb, arr);
ntdb_access_release(ntdb, arr);
}
goto fail; goto fail;
} }
if (berr) { if (berr) {
/* We found it! */ /* We found it! */
h->bucket = i; h->bucket = i;
off = val & NTDB_OFF_MASK; off = arr[i] & NTDB_OFF_MASK;
if (arr) { ntdb_access_release(ntdb, arr);
ntdb_access_release(ntdb, arr);
}
return off; return off;
} }
} }
@ -229,9 +213,7 @@ ntdb_off_t find_and_lock(struct ntdb_context *ntdb,
h->bucket = i; h->bucket = i;
} }
if (arr) { ntdb_access_release(ntdb, arr);
ntdb_access_release(ntdb, arr);
}
return 0; return 0;
fail: fail: