-
Notifications
You must be signed in to change notification settings - Fork 307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DAOS-6967 vos: Data loss on updates after uncommitted punch #4899
Changes from all commits
16f4cb7
575ab34
e4bff3d
4ab6751
8ed74f0
fa892ce
318aaf1
8baa945
23f1258
0118956
ec9f2d1
d022a62
011ba45
ea5015c
8d2fa51
78edf74
0b4464a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2334,6 +2334,118 @@ many_tx(void **state) | |
start_epoch = epoch + 1; | ||
} | ||
|
||
static struct dtx_id | ||
execute_op(daos_handle_t coh, daos_unit_oid_t oid, daos_epoch_t epoch, | ||
daos_key_t *dkey, daos_key_t *akey, d_sg_list_t *sgl, | ||
char *buf, int len, bool commit, int op) | ||
{ | ||
struct vos_ioreq req = {0}; | ||
daos_iod_t iod = {0}; | ||
int rc; | ||
|
||
vts_dtx_begin(&oid, coh, epoch, 0, &req.dth); | ||
|
||
req.oid = oid; | ||
req.coh = coh; | ||
req.xid = req.dth->dth_xid; | ||
req.flags = 0; | ||
req.dkey = dkey; | ||
req.akey = akey; | ||
if (akey) | ||
req.akey_nr = 1; | ||
|
||
if (op <= TX_OP_PUNCH_AKEY) { | ||
do_punch(&req); | ||
goto do_commit; | ||
} | ||
|
||
iod.iod_type = DAOS_IOD_SINGLE; | ||
iod.iod_recxs = NULL; | ||
iod.iod_nr = 1; | ||
req.akey = NULL; | ||
req.iod = &iod; | ||
iod.iod_name = *akey; | ||
iod.iod_size = len; | ||
d_iov_set(&sgl->sg_iovs[0], (void *)buf, iod.iod_size); | ||
sgl->sg_nr = 1; | ||
sgl->sg_nr_out = 0; | ||
req.sgl = sgl; | ||
req.fetch_sgl = sgl; | ||
do_io(&req, op); | ||
do_commit: | ||
vts_dtx_end(req.dth); | ||
if (commit && req.commit) { | ||
rc = vos_dtx_commit(coh, &req.xid, 1, NULL); | ||
assert_rc_equal(rc, 1); | ||
} | ||
|
||
return req.xid; | ||
} | ||
|
||
|
||
static void | ||
uncommitted_parent(void **state) | ||
{ | ||
struct io_test_args *arg = *state; | ||
int rc = 0; | ||
daos_key_t dkey; | ||
daos_key_t akey[2]; | ||
daos_iod_t iod; | ||
d_sg_list_t sgl; | ||
char buf[32]; | ||
daos_epoch_t epoch = start_epoch; | ||
daos_handle_t coh; | ||
char *first = "Hello"; | ||
char dkey_buf[UPDATE_DKEY_SIZE]; | ||
char akey_buf[2][UPDATE_AKEY_SIZE]; | ||
daos_unit_oid_t oid; | ||
struct dtx_id xid; | ||
|
||
test_args_reset(arg, VPOOL_SIZE); | ||
coh = arg->ctx.tc_co_hdl; | ||
|
||
memset(&iod, 0, sizeof(iod)); | ||
|
||
rc = d_sgl_init(&sgl, 1); | ||
assert_rc_equal(rc, 0); | ||
|
||
/* Set up dkey and akey */ | ||
oid = gen_oid(arg->ofeat); | ||
vts_key_gen(&dkey_buf[0], arg->dkey_size, true, arg); | ||
set_iov(&dkey, &dkey_buf[0], arg->ofeat & DAOS_OF_DKEY_UINT64); | ||
vts_key_gen(&akey_buf[0][0], arg->akey_size, true, arg); | ||
set_iov(&akey[0], &akey_buf[0][0], arg->ofeat & DAOS_OF_AKEY_UINT64); | ||
vts_key_gen(&akey_buf[1][0], arg->akey_size, true, arg); | ||
set_iov(&akey[1], &akey_buf[1][0], arg->ofeat & DAOS_OF_AKEY_UINT64); | ||
|
||
execute_op(coh, oid, epoch, &dkey, &akey[0], &sgl, first, 5, true, | ||
TX_OP_UPDATE1); | ||
epoch += 10; | ||
xid = execute_op(coh, oid, epoch, NULL, NULL, NULL, NULL, 0, false, | ||
TX_OP_PUNCH_OBJ); | ||
epoch += 10; | ||
execute_op(coh, oid, epoch, &dkey, &akey[1], &sgl, first, 5, true, | ||
TX_OP_UPDATE1); | ||
/** Commit the punch */ | ||
rc = vos_dtx_commit(coh, &xid, 1, NULL); | ||
assert_rc_equal(rc, 1); | ||
|
||
memset(buf, 'x', sizeof(buf)); | ||
epoch += 10; | ||
execute_op(coh, oid, epoch, &dkey, &akey[0], &sgl, buf, 5, true, | ||
TX_OP_FETCH1); | ||
assert_memory_equal(buf, "xxxxx", 5); | ||
|
||
memset(buf, 'x', sizeof(buf)); | ||
epoch += 10; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is unnecessary to bump the epoch again for another fetch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True but it also doesn't hurt anything There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not hurt anything, just redundant. |
||
execute_op(coh, oid, epoch, &dkey, &akey[1], &sgl, buf, 5, true, | ||
TX_OP_FETCH1); | ||
assert_memory_equal(buf, first, 5); | ||
|
||
d_sgl_fini(&sgl, false); | ||
start_epoch = epoch + 1; | ||
} | ||
|
||
static void | ||
test_multiple_key_conditionals_common(void **state, bool with_dtx) | ||
{ | ||
|
@@ -2572,6 +2684,7 @@ static const struct CMUnitTest punch_model_tests_pmdk[] = { | |
{ "VOS864: Multikey conditionals with tx", | ||
test_multiple_key_conditionals_tx, NULL, NULL }, | ||
{ "VOS865: Many transactions", many_tx, NULL, NULL }, | ||
{ "VOS866: Uncommitted parent punch", uncommitted_parent, NULL, NULL }, | ||
}; | ||
|
||
static const struct CMUnitTest punch_model_tests_all[] = { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (entry->ie_id.id_punch_minor_eph > entry->ie_id.id_update_minor_eph &&
entry->ie_id.id_punch_minor_eph > agg_arg->aa_punched_minor &&
entry->ie_id.id_epoch == agg_arg->aa_punched)
Then it is a punched entry or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the entry is punched (e.g. punch_minor > update_minor) then we will determine later that the entry is punched. But this check is only about whether it is punched entirely by the parent.