summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-11-16 18:19:48 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-11-16 18:19:48 +1100
commitc7258fd32736db32a01981c12625213d0b865310 (patch)
treebb97e79a99644cad2342df69cfd6d9c3fe491e53
parentd98d02ecc03d6dbc7b342c05d4b3e9953a8af119 (diff)
downloadmongo-c7258fd32736db32a01981c12625213d0b865310.tar.gz
Don't automatically fail inserts if the write generation check fails: compare keys instead.
-rw-r--r--dist/serial.py2
-rw-r--r--src/btree/bt_curnext.c2
-rw-r--r--src/btree/bt_curprev.c8
-rw-r--r--src/btree/col_modify.c20
-rw-r--r--src/btree/col_srch.c8
-rw-r--r--src/btree/row_modify.c38
-rw-r--r--src/btree/row_srch.c43
-rw-r--r--src/include/cache.i2
-rw-r--r--src/include/column.i25
-rw-r--r--src/include/cursor.h3
-rw-r--r--src/include/serial_funcs.i36
-rw-r--r--src/lsm/lsm_worker.c4
12 files changed, 129 insertions, 62 deletions
diff --git a/dist/serial.py b/dist/serial.py
index 8772c4bd6bc..46ebc86d0c2 100644
--- a/dist/serial.py
+++ b/dist/serial.py
@@ -20,6 +20,7 @@ Serial('col_append', [
SerialArg('uint32_t', 'write_gen'),
SerialArg('WT_INSERT_HEAD **', 'insheadp'),
SerialArg('WT_INSERT ***', 'ins_stack'),
+ SerialArg('WT_INSERT **', 'next_stack'),
SerialArg('WT_INSERT_HEAD **', 'new_inslist', 1),
SerialArg('WT_INSERT_HEAD *', 'new_inshead', 1),
SerialArg('WT_INSERT *', 'new_ins', 1),
@@ -31,6 +32,7 @@ Serial('insert', [
SerialArg('uint32_t', 'write_gen'),
SerialArg('WT_INSERT_HEAD **', 'inshead'),
SerialArg('WT_INSERT ***', 'ins_stack'),
+ SerialArg('WT_INSERT **', 'next_stack'),
SerialArg('WT_INSERT_HEAD **', 'new_inslist', 1),
SerialArg('WT_INSERT_HEAD *', 'new_inshead', 1),
SerialArg('WT_INSERT *', 'new_ins', 1),
diff --git a/src/btree/bt_curnext.c b/src/btree/bt_curnext.c
index d08f113fd90..6bfc4a8ad89 100644
--- a/src/btree/bt_curnext.c
+++ b/src/btree/bt_curnext.c
@@ -100,7 +100,7 @@ __cursor_fix_next(WT_CURSOR_BTREE *cbt, int newpage)
new_page: /* Check any insert list for a matching record. */
cbt->ins_head = WT_COL_UPDATE_SINGLE(cbt->page);
cbt->ins = __col_insert_search(
- cbt->ins_head, cbt->ins_stack, cbt->recno);
+ cbt->ins_head, cbt->ins_stack, cbt->next_stack, cbt->recno);
if (cbt->ins != NULL &&
cbt->recno != WT_INSERT_RECNO(cbt->ins))
cbt->ins = NULL;
diff --git a/src/btree/bt_curprev.c b/src/btree/bt_curprev.c
index 650f09f1a87..e836615c4bc 100644
--- a/src/btree/bt_curprev.c
+++ b/src/btree/bt_curprev.c
@@ -54,7 +54,8 @@ restart:
session, cbt, cbt->ins_head, &key));
} else
cbt->ins = __col_insert_search(cbt->ins_head,
- cbt->ins_stack, WT_INSERT_RECNO(current));
+ cbt->ins_stack, cbt->next_stack,
+ WT_INSERT_RECNO(current));
}
/*
@@ -83,6 +84,7 @@ restart:
if (ins == NULL || ins == current)
for (; i >= 0; i--) {
cbt->ins_stack[i] = NULL;
+ cbt->next_stack[i] = NULL;
ins = cbt->ins_head->head[i];
if (ins != NULL && ins != current)
break;
@@ -96,12 +98,14 @@ restart:
*/
if (ins == NULL) {
cbt->ins_stack[0] = NULL;
+ cbt->next_stack[0] = NULL;
goto restart;
}
if (ins->next[i] != current) /* Stay at this level */
ins = ins->next[i];
else { /* Drop down a level */
cbt->ins_stack[i] = &ins->next[i];
+ cbt->next_stack[i] = ins->next[i];
--i;
}
}
@@ -231,7 +235,7 @@ __cursor_fix_prev(WT_CURSOR_BTREE *cbt, int newpage)
new_page: /* Check any insert list for a matching record. */
cbt->ins_head = WT_COL_UPDATE_SINGLE(cbt->page);
cbt->ins = __col_insert_search(
- cbt->ins_head, cbt->ins_stack, cbt->recno);
+ cbt->ins_head, cbt->ins_stack, cbt->next_stack, cbt->recno);
if (cbt->ins != NULL &&
cbt->recno != WT_INSERT_RECNO(cbt->ins))
cbt->ins = NULL;
diff --git a/src/btree/col_modify.c b/src/btree/col_modify.c
index 7035ccdc74b..fbe7898dc40 100644
--- a/src/btree/col_modify.c
+++ b/src/btree/col_modify.c
@@ -134,8 +134,10 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int op)
if (*inshead == NULL) {
new_inshead_size = sizeof(WT_INSERT_HEAD);
WT_ERR(__wt_calloc_def(session, 1, &new_inshead));
- for (i = 0; i < WT_SKIP_MAXDEPTH; i++)
+ for (i = 0; i < WT_SKIP_MAXDEPTH; i++) {
cbt->ins_stack[i] = &new_inshead->head[i];
+ cbt->next_stack[i] = NULL;
+ }
cbt->ins_head = new_inshead;
}
@@ -164,7 +166,8 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int op)
ins_copy = ins;
WT_ERR(__wt_col_append_serial(session,
- page, cbt->write_gen, inshead, cbt->ins_stack,
+ page, cbt->write_gen, inshead,
+ cbt->ins_stack, cbt->next_stack,
&new_inslist, new_inslist_size,
&new_inshead, new_inshead_size,
&ins, ins_size, skipdepth));
@@ -173,8 +176,8 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int op)
cbt->recno = WT_INSERT_RECNO(ins_copy);
} else
WT_ERR(__wt_insert_serial(session,
- page, cbt->write_gen,
- inshead, cbt->ins_stack,
+ page, cbt->write_gen, inshead,
+ cbt->ins_stack, cbt->next_stack,
&new_inslist, new_inslist_size,
&new_inshead, new_inshead_size,
&ins, ins_size, skipdepth));
@@ -230,7 +233,7 @@ int
__wt_col_append_serial_func(WT_SESSION_IMPL *session, void *args)
{
WT_BTREE *btree;
- WT_INSERT *ins, *new_ins, ***ins_stack;
+ WT_INSERT *ins, *new_ins, ***ins_stack, **next_stack;
WT_INSERT_HEAD *inshead, **insheadp, **new_inslist, *new_inshead;
WT_PAGE *page;
uint64_t recno;
@@ -239,8 +242,9 @@ __wt_col_append_serial_func(WT_SESSION_IMPL *session, void *args)
btree = session->btree;
- __wt_col_append_unpack(args, &page, &write_gen, &insheadp,
- &ins_stack, &new_inslist, &new_inshead, &new_ins, &skipdepth);
+ __wt_col_append_unpack(args,
+ &page, &write_gen, &insheadp, &ins_stack, &next_stack,
+ &new_inslist, &new_inshead, &new_ins, &skipdepth);
/* Check the page's write-generation. */
WT_RET(__wt_page_write_gen_check(session, page, write_gen));
@@ -259,7 +263,7 @@ __wt_col_append_serial_func(WT_SESSION_IMPL *session, void *args)
if ((recno = WT_INSERT_RECNO(new_ins)) == 0)
recno = WT_INSERT_RECNO(new_ins) = ++btree->last_recno;
- ins = __col_insert_search(inshead, ins_stack, recno);
+ ins = __col_insert_search(inshead, ins_stack, next_stack, recno);
/* If we find the record number, there's been a race. */
if (ins != NULL && WT_INSERT_RECNO(ins) == recno)
diff --git a/src/btree/col_srch.c b/src/btree/col_srch.c
index c2fbf80c2e2..ffcca036cab 100644
--- a/src/btree/col_srch.c
+++ b/src/btree/col_srch.c
@@ -117,8 +117,8 @@ __wt_col_search(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int is_modify)
* For that reason, don't set the cursor's WT_INSERT_HEAD/WT_INSERT pair
* until we know we have a useful entry.
*/
- if ((ins =
- __col_insert_search(ins_head, cbt->ins_stack, recno)) != NULL)
+ if ((ins = __col_insert_search(
+ ins_head, cbt->ins_stack, cbt->next_stack, recno)) != NULL)
if (recno == WT_INSERT_RECNO(ins)) {
cbt->ins_head = ins_head;
cbt->ins = ins;
@@ -135,8 +135,8 @@ past_end:
* past the end of the table.
*/
cbt->ins_head = WT_COL_APPEND(page);
- if ((cbt->ins =
- __col_insert_search(cbt->ins_head, cbt->ins_stack, recno)) == NULL)
+ if ((cbt->ins = __col_insert_search(
+ cbt->ins_head, cbt->ins_stack, cbt->next_stack, recno)) == NULL)
cbt->compare = -1;
else {
cbt->recno = WT_INSERT_RECNO(cbt->ins);
diff --git a/src/btree/row_modify.c b/src/btree/row_modify.c
index 2ad6947d6de..64123bc53e5 100644
--- a/src/btree/row_modify.c
+++ b/src/btree/row_modify.c
@@ -121,8 +121,10 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int is_remove)
if (*inshead == NULL) {
new_inshead_size = sizeof(WT_INSERT_HEAD);
WT_ERR(__wt_calloc_def(session, 1, &new_inshead));
- for (i = 0; i < WT_SKIP_MAXDEPTH; i++)
+ for (i = 0; i < WT_SKIP_MAXDEPTH; i++) {
cbt->ins_stack[i] = &new_inshead->head[i];
+ cbt->next_stack[i] = NULL;
+ }
cbt->ins_head = new_inshead;
}
@@ -144,7 +146,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int is_remove)
/* Insert the WT_INSERT structure. */
WT_ERR(__wt_insert_serial(session, page, cbt->write_gen,
- inshead, cbt->ins_stack,
+ inshead, cbt->ins_stack, cbt->next_stack,
&new_inslist, new_inslist_size,
&new_inshead, new_inshead_size,
&ins, ins_size, skipdepth));
@@ -205,17 +207,38 @@ __wt_row_insert_alloc(WT_SESSION_IMPL *session,
int
__wt_insert_serial_func(WT_SESSION_IMPL *session, void *args)
{
- WT_INSERT *new_ins, ***ins_stack;
+ WT_INSERT *new_ins, ***ins_stack, **next_stack;
WT_INSERT_HEAD *inshead, **insheadp, **new_inslist, *new_inshead;
WT_PAGE *page;
uint32_t write_gen;
u_int i, skipdepth;
__wt_insert_unpack(args, &page, &write_gen, &insheadp,
- &ins_stack, &new_inslist, &new_inshead, &new_ins, &skipdepth);
+ &ins_stack, &next_stack,
+ &new_inslist, &new_inshead, &new_ins, &skipdepth);
- /* Check the page's write-generation. */
- WT_RET(__wt_page_write_gen_check(session, page, write_gen));
+ if ((inshead = *insheadp) == NULL)
+ inshead = new_inshead;
+
+ /*
+ * Check the page's write-generation: if that fails, check whether we
+ * are still in the expected position, and no item has been added where
+ * our insert belongs.
+ */
+ if (page->modify->write_gen + 1 == page->modify->disk_gen)
+ return (WT_RESTART);
+
+ if (page->modify->write_gen != write_gen) {
+ for (i = 0; i < skipdepth; i++) {
+ if (ins_stack[i] == NULL ||
+ *ins_stack[i] != next_stack[i])
+ return (WT_RESTART);
+ if (next_stack[i] == NULL &&
+ inshead->tail[i] != NULL &&
+ ins_stack[i] != &inshead->tail[i]->next[i])
+ return (WT_RESTART);
+ }
+ }
/*
* Publish: First, point the new WT_INSERT item's skiplist references
@@ -223,10 +246,9 @@ __wt_insert_serial_func(WT_SESSION_IMPL *session, void *args)
* update the skiplist elements that reference the new WT_INSERT item,
* this ensures the list is never inconsistent.
*/
- if ((inshead = *insheadp) == NULL)
- inshead = new_inshead;
for (i = 0; i < skipdepth; i++)
new_ins->next[i] = *ins_stack[i];
+
WT_WRITE_BARRIER();
for (i = 0; i < skipdepth; i++) {
if (inshead->tail[i] == NULL ||
diff --git a/src/btree/row_srch.c b/src/btree/row_srch.c
index 885979bffbf..f005db24a1e 100644
--- a/src/btree/row_srch.c
+++ b/src/btree/row_srch.c
@@ -16,27 +16,39 @@ __wt_search_insert(WT_SESSION_IMPL *session,
WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *inshead, WT_ITEM *srch_key)
{
WT_BTREE *btree;
- WT_INSERT **insp, *ret_ins;
+ WT_INSERT **insp, *last_ins, *ret_ins;
WT_ITEM insert_key;
int cmp, i;
+ btree = session->btree;
+
/* If there's no insert chain to search, we're done. */
if ((ret_ins = WT_SKIP_LAST(inshead)) == NULL) {
cbt->ins = NULL;
+ cbt->next_stack[0] = NULL;
return (0);
}
- btree = session->btree;
-
/* Fast-path appends. */
insert_key.data = WT_INSERT_KEY(ret_ins);
insert_key.size = WT_INSERT_KEY_SIZE(ret_ins);
(void)WT_BTREE_CMP(session, btree, srch_key, &insert_key, cmp);
if (cmp >= 0) {
- for (i = WT_SKIP_MAXDEPTH - 1; i >= 0; i--)
- cbt->ins_stack[i] = (inshead->tail[i] != NULL) ?
- &inshead->tail[i]->next[i] :
- &inshead->head[i];
+ /*
+ * XXX We may race with another appending thread.
+ *
+ * To catch that case, rely on the atomic pointer read above
+ * and set the next stack to NULL here. If we have raced with
+ * another thread, one of the next pointers will not be NULL by
+ * the time they are checked against the next stack inside the
+ * serialized insert function.
+ */
+ for (i = WT_SKIP_MAXDEPTH - 1; i >= 0; i--) {
+ cbt->ins_stack[i] = (i == 0) ? &ret_ins->next[0] :
+ (inshead->tail[i] != NULL) ?
+ &inshead->tail[i]->next[i] : &inshead->head[i];
+ cbt->next_stack[i] = NULL;
+ }
cbt->compare = -cmp;
cbt->ins = ret_ins;
return (0);
@@ -46,9 +58,10 @@ __wt_search_insert(WT_SESSION_IMPL *session,
* The insert list is a skip list: start at the highest skip level, then
* go as far as possible at each level before stepping down to the next.
*/
- ret_ins = NULL;
+ last_ins = ret_ins = NULL;
for (i = WT_SKIP_MAXDEPTH - 1, insp = &inshead->head[i]; i >= 0;) {
- if (*insp == NULL) {
+ if ((ret_ins = *insp) == NULL) {
+ cbt->next_stack[i] = NULL;
cbt->ins_stack[i--] = insp--;
continue;
}
@@ -57,8 +70,8 @@ __wt_search_insert(WT_SESSION_IMPL *session,
* Comparisons may be repeated as we drop down skiplist levels;
* don't repeat comparisons, they might be expensive.
*/
- if (ret_ins != *insp) {
- ret_ins = *insp;
+ if (ret_ins != last_ins) {
+ last_ins = ret_ins;
insert_key.data = WT_INSERT_KEY(ret_ins);
insert_key.size = WT_INSERT_KEY_SIZE(ret_ins);
WT_RET(WT_BTREE_CMP(
@@ -68,10 +81,14 @@ __wt_search_insert(WT_SESSION_IMPL *session,
if (cmp > 0) /* Keep going at this level */
insp = &ret_ins->next[i];
else if (cmp == 0)
- for (; i >= 0; i--)
+ for (; i >= 0; i--) {
+ cbt->next_stack[i] = ret_ins->next[i];
cbt->ins_stack[i] = &ret_ins->next[i];
- else /* Drop down a level */
+ }
+ else { /* Drop down a level */
+ cbt->next_stack[i] = ret_ins;
cbt->ins_stack[i--] = insp--;
+ }
}
/*
diff --git a/src/include/cache.i b/src/include/cache.i
index 4312304d968..5ecc0c11701 100644
--- a/src/include/cache.i
+++ b/src/include/cache.i
@@ -55,7 +55,7 @@ __wt_cache_full_check(WT_SESSION_IMPL *session)
for (wake = 0;; wake = (wake + 1) % 100) {
__wt_eviction_check(session, &lockout, wake == 0);
if (!lockout || F_ISSET(session,
- WT_SESSION_NO_CACHE_CHECK | WT_SESSION_SCHEMA_LOCKED))
+ WT_SESSION_NO_CACHE_CHECK | WT_SESSION_SCHEMA_LOCKED))
return (0);
if ((btree = session->btree) != NULL && F_ISSET(btree,
WT_BTREE_BULK | WT_BTREE_NO_CACHE | WT_BTREE_NO_EVICTION))
diff --git a/src/include/column.i b/src/include/column.i
index 83b2783dbf0..0cf83a6d2e9 100644
--- a/src/include/column.i
+++ b/src/include/column.i
@@ -58,8 +58,8 @@ __col_insert_search_match(WT_INSERT_HEAD *inshead, uint64_t recno)
* Search a column-store insert list, creating a skiplist stack as we go.
*/
static inline WT_INSERT *
-__col_insert_search(
- WT_INSERT_HEAD *inshead, WT_INSERT ***ins_stack, uint64_t recno)
+__col_insert_search(WT_INSERT_HEAD *inshead,
+ WT_INSERT ***ins_stack, WT_INSERT **next_stack, uint64_t recno)
{
WT_INSERT **insp, *ret_ins;
uint64_t ins_recno;
@@ -71,9 +71,12 @@ __col_insert_search(
/* Fast path appends. */
if (recno >= WT_INSERT_RECNO(ret_ins)) {
- for (i = 0; i < WT_SKIP_MAXDEPTH; i++)
- ins_stack[i] = (inshead->tail[i] != NULL) ?
+ for (i = 0; i < WT_SKIP_MAXDEPTH; i++) {
+ ins_stack[i] = (i == 0) ? &ret_ins->next[0] :
+ (inshead->tail[i] != NULL) ?
&inshead->tail[i]->next[i] : &inshead->head[i];
+ next_stack[i] = NULL;
+ }
return (ret_ins);
}
@@ -82,22 +85,26 @@ __col_insert_search(
* go as far as possible at each level before stepping down to the next.
*/
for (i = WT_SKIP_MAXDEPTH - 1, insp = &inshead->head[i]; i >= 0; ) {
- if (*insp == NULL) {
+ if ((ret_ins = *insp) == NULL) {
+ next_stack[i] = NULL;
ins_stack[i--] = insp--;
continue;
}
- ret_ins = *insp;
ins_recno = WT_INSERT_RECNO(ret_ins);
cmp = (recno == ins_recno) ? 0 : (recno < ins_recno) ? -1 : 1;
if (cmp > 0) /* Keep going at this level */
- insp = &(*insp)->next[i];
+ insp = &ret_ins->next[i];
else if (cmp == 0) /* Exact match: return */
- for (; i >= 0; i--)
+ for (; i >= 0; i--) {
+ next_stack[i] = ret_ins->next[i];
ins_stack[i] = &ret_ins->next[i];
- else /* Drop down a level */
+ }
+ else { /* Drop down a level */
+ next_stack[i] = ret_ins;
ins_stack[i--] = insp--;
+ }
}
return (ret_ins);
}
diff --git a/src/include/cursor.h b/src/include/cursor.h
index 3afc5a8ea7c..85c61076b75 100644
--- a/src/include/cursor.h
+++ b/src/include/cursor.h
@@ -36,6 +36,9 @@ struct __wt_cursor_btree {
/* Search stack */
WT_INSERT **ins_stack[WT_SKIP_MAXDEPTH];
+ /* Next item(s) found during search */
+ WT_INSERT *next_stack[WT_SKIP_MAXDEPTH];
+
uint64_t recno; /* Record number */
uint32_t write_gen; /* Saved leaf page's write generation */
diff --git a/src/include/serial_funcs.i b/src/include/serial_funcs.i
index bbddf47042b..4b39b877088 100644
--- a/src/include/serial_funcs.i
+++ b/src/include/serial_funcs.i
@@ -5,6 +5,7 @@ typedef struct {
uint32_t write_gen;
WT_INSERT_HEAD **insheadp;
WT_INSERT ***ins_stack;
+ WT_INSERT **next_stack;
WT_INSERT_HEAD **new_inslist;
size_t new_inslist_size;
int new_inslist_taken;
@@ -20,10 +21,10 @@ typedef struct {
static inline int
__wt_col_append_serial(
WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t write_gen,
- WT_INSERT_HEAD **insheadp, WT_INSERT ***ins_stack, WT_INSERT_HEAD
- ***new_inslistp, size_t new_inslist_size, WT_INSERT_HEAD
- **new_insheadp, size_t new_inshead_size, WT_INSERT **new_insp, size_t
- new_ins_size, u_int skipdepth)
+ WT_INSERT_HEAD **insheadp, WT_INSERT ***ins_stack, WT_INSERT
+ **next_stack, WT_INSERT_HEAD ***new_inslistp, size_t new_inslist_size,
+ WT_INSERT_HEAD **new_insheadp, size_t new_inshead_size, WT_INSERT
+ **new_insp, size_t new_ins_size, u_int skipdepth)
{
__wt_col_append_args _args, *args = &_args;
WT_DECL_RET;
@@ -36,6 +37,8 @@ __wt_col_append_serial(
args->ins_stack = ins_stack;
+ args->next_stack = next_stack;
+
if (new_inslistp == NULL)
args->new_inslist = NULL;
else {
@@ -81,9 +84,9 @@ __wt_col_append_serial(
static inline void
__wt_col_append_unpack(
void *untyped_args, WT_PAGE **pagep, uint32_t *write_genp,
- WT_INSERT_HEAD ***insheadpp, WT_INSERT ****ins_stackp, WT_INSERT_HEAD
- ***new_inslistp, WT_INSERT_HEAD **new_insheadp, WT_INSERT **new_insp,
- u_int *skipdepthp)
+ WT_INSERT_HEAD ***insheadpp, WT_INSERT ****ins_stackp, WT_INSERT
+ ***next_stackp, WT_INSERT_HEAD ***new_inslistp, WT_INSERT_HEAD
+ **new_insheadp, WT_INSERT **new_insp, u_int *skipdepthp)
{
__wt_col_append_args *args = (__wt_col_append_args *)untyped_args;
@@ -91,6 +94,7 @@ __wt_col_append_unpack(
*write_genp = args->write_gen;
*insheadpp = args->insheadp;
*ins_stackp = args->ins_stack;
+ *next_stackp = args->next_stack;
*new_inslistp = args->new_inslist;
*new_insheadp = args->new_inshead;
*new_insp = args->new_ins;
@@ -138,6 +142,7 @@ typedef struct {
uint32_t write_gen;
WT_INSERT_HEAD **inshead;
WT_INSERT ***ins_stack;
+ WT_INSERT **next_stack;
WT_INSERT_HEAD **new_inslist;
size_t new_inslist_size;
int new_inslist_taken;
@@ -153,10 +158,10 @@ typedef struct {
static inline int
__wt_insert_serial(
WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t write_gen,
- WT_INSERT_HEAD **inshead, WT_INSERT ***ins_stack, WT_INSERT_HEAD
- ***new_inslistp, size_t new_inslist_size, WT_INSERT_HEAD
- **new_insheadp, size_t new_inshead_size, WT_INSERT **new_insp, size_t
- new_ins_size, u_int skipdepth)
+ WT_INSERT_HEAD **inshead, WT_INSERT ***ins_stack, WT_INSERT
+ **next_stack, WT_INSERT_HEAD ***new_inslistp, size_t new_inslist_size,
+ WT_INSERT_HEAD **new_insheadp, size_t new_inshead_size, WT_INSERT
+ **new_insp, size_t new_ins_size, u_int skipdepth)
{
__wt_insert_args _args, *args = &_args;
WT_DECL_RET;
@@ -169,6 +174,8 @@ __wt_insert_serial(
args->ins_stack = ins_stack;
+ args->next_stack = next_stack;
+
if (new_inslistp == NULL)
args->new_inslist = NULL;
else {
@@ -214,9 +221,9 @@ __wt_insert_serial(
static inline void
__wt_insert_unpack(
void *untyped_args, WT_PAGE **pagep, uint32_t *write_genp,
- WT_INSERT_HEAD ***insheadp, WT_INSERT ****ins_stackp, WT_INSERT_HEAD
- ***new_inslistp, WT_INSERT_HEAD **new_insheadp, WT_INSERT **new_insp,
- u_int *skipdepthp)
+ WT_INSERT_HEAD ***insheadp, WT_INSERT ****ins_stackp, WT_INSERT
+ ***next_stackp, WT_INSERT_HEAD ***new_inslistp, WT_INSERT_HEAD
+ **new_insheadp, WT_INSERT **new_insp, u_int *skipdepthp)
{
__wt_insert_args *args = (__wt_insert_args *)untyped_args;
@@ -224,6 +231,7 @@ __wt_insert_unpack(
*write_genp = args->write_gen;
*insheadp = args->inshead;
*ins_stackp = args->ins_stack;
+ *next_stackp = args->next_stack;
*new_inslistp = args->new_inslist;
*new_insheadp = args->new_inshead;
*new_insp = args->new_ins;
diff --git a/src/lsm/lsm_worker.c b/src/lsm/lsm_worker.c
index 429c38d39ed..647d79a3897 100644
--- a/src/lsm/lsm_worker.c
+++ b/src/lsm/lsm_worker.c
@@ -186,11 +186,11 @@ __wt_lsm_checkpoint_worker(void *arg)
}
++j;
- __wt_spin_lock(session, &lsm_tree->lock);
+ __wt_writelock(session, lsm_tree->rwlock);
F_SET(chunk, WT_LSM_CHUNK_ONDISK);
++lsm_tree->dsk_gen;
ret = __wt_lsm_meta_write(session, lsm_tree);
- __wt_spin_unlock(session, &lsm_tree->lock);
+ __wt_rwunlock(session, lsm_tree->rwlock);
if (ret != 0) {
(void)__wt_err(session, ret,