Skip to content
This repository was archived by the owner on May 3, 2024. It is now read-only.

Commit 70faca9

Browse files
committed
Fail dix operations that don't meet the specified min_success
Signed-off-by: Tim Shaffer <[email protected]>
1 parent 2730e68 commit 70faca9

File tree

5 files changed

+51
-48
lines changed

5 files changed

+51
-48
lines changed

dix/req.c

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,14 @@ M0_INTERNAL int m0_dix_req_wait(struct m0_dix_req *req, uint64_t states,
209209
static void dix_req_init(struct m0_dix_req *req,
210210
struct m0_dix_cli *cli,
211211
struct m0_sm_group *grp,
212+
uint32_t min_success,
212213
bool meta)
213214
{
215+
M0_PRE(min_success > 0);
214216
M0_SET0(req);
215217
req->dr_cli = cli;
216218
req->dr_is_meta = meta;
219+
req->dr_min_success = min_success;
217220
m0_sm_init(&req->dr_sm, &dix_req_sm_conf, DIXREQ_INIT, grp);
218221
m0_sm_addb2_counter_init(&req->dr_sm);
219222
}
@@ -222,14 +225,15 @@ M0_INTERNAL void m0_dix_mreq_init(struct m0_dix_req *req,
222225
struct m0_dix_cli *cli,
223226
struct m0_sm_group *grp)
224227
{
225-
dix_req_init(req, cli, grp, true);
228+
dix_req_init(req, cli, grp, 1, true);
226229
}
227230

228231
M0_INTERNAL void m0_dix_req_init(struct m0_dix_req *req,
229232
struct m0_dix_cli *cli,
230-
struct m0_sm_group *grp)
233+
struct m0_sm_group *grp,
234+
uint32_t min_success)
231235
{
232-
dix_req_init(req, cli, grp, false);
236+
dix_req_init(req, cli, grp, min_success, false);
233237
}
234238

235239
static enum m0_dix_req_state dix_req_state(const struct m0_dix_req *req)
@@ -1402,6 +1406,20 @@ static void dix_rop(struct m0_dix_req *req)
14021406
M0_LEAVE();
14031407
}
14041408

1409+
/** Checks if the given cas get reply has a newer version of the value */
1410+
static bool dix_item_version_cmp(struct m0_dix_item *ditem,
1411+
struct m0_cas_get_reply *get_rep) {
1412+
/*
1413+
* TODO: once cas versions are propagated, check if the get reply
1414+
* has a newer version than seen previously. Will need to add
1415+
* version info to struct m0_dix_item. This function should return
1416+
* true if no previous value is set, or if the previous value has
1417+
* an older version. For now, always return true so the last
1418+
* reply in the array wins.
1419+
*/
1420+
return true;
1421+
}
1422+
14051423
static void dix_item_rc_update(struct m0_dix_req *req,
14061424
struct m0_cas_req *creq,
14071425
uint64_t key_idx,
@@ -1418,7 +1436,8 @@ static void dix_item_rc_update(struct m0_dix_req *req,
14181436
case DIX_GET:
14191437
m0_cas_get_rep(creq, key_idx, &get_rep);
14201438
rc = get_rep.cge_rc;
1421-
if (rc == 0) {
1439+
if (rc == 0 && dix_item_version_cmp(ditem, &get_rep)) {
1440+
m0_buf_free(&ditem->dxi_val);
14221441
ditem->dxi_val = get_rep.cge_val;
14231442
/* Value will be freed at m0_dix_req_fini(). */
14241443
m0_cas_rep_mlock(creq, key_idx);
@@ -1625,24 +1644,28 @@ static void dix_rop_completed(struct m0_sm_group *grp, struct m0_sm_ast *ast)
16251644
struct m0_dix_rop_ctx *rop_del_phase2 = NULL;
16261645
bool del_phase2 = false;
16271646
struct m0_dix_cas_rop *cas_rop;
1647+
uint32_t successful_ops = 0;
16281648

16291649
(void)grp;
16301650
if (req->dr_type == DIX_NEXT)
16311651
m0_dix_next_result_prepare(req);
16321652
else {
1653+
successful_ops = m0_tl_reduce(cas_rop, scan, &rop->dg_cas_reqs, 0,
1654+
+ !!(scan->crp_creq.ccr_sm.sm_rc == 0));
1655+
16331656
/*
1634-
* Consider DIX request to be successful if there is at least
1635-
* one successful CAS request.
1657+
* If enough operations succeeded to satisfy min_success,
1658+
* ignore any operations that failed. If we don't have enough,
1659+
* count all operations when deciding overall success (ensures the
1660+
* overall operation is considered a failure).
16361661
*/
1637-
if (m0_tl_forall(cas_rop, cas_rop,
1638-
&rop->dg_cas_reqs,
1639-
cas_rop->crp_creq.ccr_sm.sm_rc != 0))
1640-
dix_cas_rop_rc_update(cas_rop_tlist_tail(
1641-
&rop->dg_cas_reqs), 0);
16421662

1663+
M0_ASSERT(req->dr_min_success > 0);
16431664
m0_tl_for (cas_rop, &rop->dg_cas_reqs, cas_rop) {
1644-
if (cas_rop->crp_creq.ccr_sm.sm_rc == 0)
1665+
if (successful_ops < req->dr_min_success ||
1666+
cas_rop->crp_creq.ccr_sm.sm_rc == 0) {
16451667
dix_cas_rop_rc_update(cas_rop, 0);
1668+
}
16461669
m0_cas_req_fini(&cas_rop->crp_creq);
16471670
} m0_tl_endfor;
16481671
}
@@ -1956,29 +1979,6 @@ static int dix_spare_target_with_data(struct m0_dix_rec_op *rec_op,
19561979
true);
19571980
}
19581981

1959-
static void dix_online_unit_choose(struct m0_dix_req *req,
1960-
struct m0_dix_rec_op *rec_op)
1961-
{
1962-
struct m0_dix_pg_unit *pgu;
1963-
uint64_t start_unit;
1964-
uint64_t i;
1965-
uint64_t j;
1966-
1967-
M0_ENTRY();
1968-
M0_PRE(req->dr_type == DIX_GET);
1969-
start_unit = req->dr_items[rec_op->dgp_item].dxi_pg_unit;
1970-
M0_ASSERT(start_unit < dix_rec_op_spare_offset(rec_op));
1971-
for (i = 0; i < start_unit; i++)
1972-
rec_op->dgp_units[i].dpu_unavail = true;
1973-
for (i = start_unit; i < rec_op->dgp_units_nr; i++) {
1974-
pgu = &rec_op->dgp_units[i];
1975-
if (!pgu->dpu_is_spare && !pgu->dpu_unavail)
1976-
break;
1977-
}
1978-
for (j = i + 1; j < rec_op->dgp_units_nr; j++)
1979-
rec_op->dgp_units[j].dpu_unavail = true;
1980-
}
1981-
19821982
static void dix_pg_unit_pd_assign(struct m0_dix_pg_unit *pgu,
19831983
struct m0_pooldev *pd)
19841984
{
@@ -2135,15 +2135,6 @@ static void dix_rop_units_set(struct m0_dix_req *req)
21352135
}
21362136

21372137
m0_rwlock_read_unlock(&pm->pm_lock);
2138-
2139-
/*
2140-
* Only one CAS GET request should be sent for every record.
2141-
* Choose the best destination for every record.
2142-
*/
2143-
if (req->dr_type == DIX_GET) {
2144-
for (i = 0; i < rop->dg_rec_ops_nr; i++)
2145-
dix_online_unit_choose(req, &rop->dg_rec_ops[i]);
2146-
}
21472138
}
21482139

21492140
static bool dix_pg_unit_skip(struct m0_dix_req *req,

dix/req.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ struct m0_dix_req {
253253
* starting key in DIX_NEXT request.
254254
*/
255255
uint32_t *dr_recs_nr;
256+
/**
257+
* Minimum number of successful CAS operations to treat
258+
* parent DIX operation as successful.
259+
*/
260+
uint32_t dr_min_success;
256261
/** Request flags bitmask of m0_cas_op_flags values. */
257262
uint32_t dr_flags;
258263

@@ -283,7 +288,8 @@ struct m0_dix_next_reply {
283288
/** Initialises DIX request. */
284289
M0_INTERNAL void m0_dix_req_init(struct m0_dix_req *req,
285290
struct m0_dix_cli *cli,
286-
struct m0_sm_group *grp);
291+
struct m0_sm_group *grp,
292+
uint32_t min_success);
287293

288294
/**
289295
* Initialises DIX request operating with meta-indices.

dix/ut/client_ut.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ static int dix_common_idx_flagged_op(const struct m0_dix *indices,
12441244
int rc;
12451245
int i;
12461246

1247-
m0_dix_req_init(&req, &dix_ut_cctx.cl_cli, dix_ut_cctx.cl_grp);
1247+
m0_dix_req_init(&req, &dix_ut_cctx.cl_cli, dix_ut_cctx.cl_grp, 1);
12481248
m0_dix_req_lock(&req);
12491249
switch (type) {
12501250
case REQ_CREATE:
@@ -1294,7 +1294,7 @@ static int dix_common_rec_op(const struct m0_dix *index,
12941294
int i;
12951295
int k = 0;
12961296

1297-
m0_dix_req_init(&req, &dix_ut_cctx.cl_cli, dix_ut_cctx.cl_grp);
1297+
m0_dix_req_init(&req, &dix_ut_cctx.cl_cli, dix_ut_cctx.cl_grp, 1);
12981298
m0_dix_req_lock(&req);
12991299
switch (type) {
13001300
case REQ_PUT:

motr/client_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ struct m0_op_idx {
229229
struct m0_sm_group *oi_sm_grp;
230230
struct m0_ast_rc oi_ar;
231231

232+
/**
233+
* Minimum number of successful CAS operations to treat
234+
* parent DIX operation as successful.
235+
*/
236+
uint32_t oi_min_success;
237+
232238
/* A bit-mask of m0_op_idx_flags. */
233239
uint32_t oi_flags;
234240

motr/idx_dix.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ static int dix_req_create(struct m0_op_idx *oi,
663663
m0_clink_init(&req->idr_dtx_clink, dixreq_clink_dtx_cb);
664664
if (idx_is_distributed(oi)) {
665665
m0_dix_req_init(&req->idr_dreq, op_dixc(oi),
666-
oi->oi_sm_grp);
666+
oi->oi_sm_grp, oi->oi_min_success);
667667
to_dix_map(&oi->oi_oc.oc_op, &req->idr_dreq);
668668
req->idr_dreq.dr_dtx = oi->oi_dtx;
669669
m0_clink_init(&req->idr_clink, dixreq_clink_cb);

0 commit comments

Comments
 (0)