diff --git a/src/container/container_iv.c b/src/container/container_iv.c index 05a15fb751d..62f9b77caee 100644 --- a/src/container/container_iv.c +++ b/src/container/container_iv.c @@ -1,6 +1,6 @@ /** * (C) Copyright 2019-2023 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -1587,7 +1587,7 @@ cont_iv_prop_fetch_ult(void *data) iv_entry, iv_entry_size, iv_entry_size, false /* retry */); if (rc) { - DL_CDEBUG(rc == -DER_NOTLEADER, DB_ANY, DLOG_ERR, rc, + DL_CDEBUG(rc == -DER_NOTLEADER || rc == -DER_CONT_NONEXIST, DB_ANY, DLOG_ERR, rc, DF_CONT ": cont_iv_fetch failed", DP_CONT(pool->sp_uuid, arg->cont_uuid)); D_GOTO(out, rc); } diff --git a/src/include/daos_srv/object.h b/src/include/daos_srv/object.h index 9fd82b76d0d..33d23464e1f 100644 --- a/src/include/daos_srv/object.h +++ b/src/include/daos_srv/object.h @@ -1,6 +1,6 @@ /* * (C) Copyright 2022 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -35,7 +35,7 @@ struct ds_obj_enum_arg { int kds_cap; int kds_len; d_sg_list_t *sgl; - d_iov_t csum_iov; + d_iov_t oea_csum_iov; uint32_t ec_cell_sz; int sgl_idx; }; diff --git a/src/object/cli_ec.c b/src/object/cli_ec.c index 7a4d72e3f7d..e11bc9e54e8 100644 --- a/src/object/cli_ec.c +++ b/src/object/cli_ec.c @@ -1,6 +1,6 @@ /** * (C) Copyright 2016-2023 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -2783,6 +2783,12 @@ obj_ec_recov_fill_back(daos_iod_t *iod, d_sg_list_t *sgl, obj_ec_sgl_copy(sgl, iod_off, stripe_buf + tmp_off, rec_nr * iod_size); + /* Just for code integrity add the iod_off as it consumed + * some buffers. In reality as recov_recx/ovl will not cross + * multiple stripes so ovl will only overlap with one + * stripe, so it actually will not affect correctness. + */ + iod_off += rec_nr * iod_size; ovl.rx_idx += rec_nr; ovl.rx_nr -= rec_nr; if (ovl.rx_nr == 0) diff --git a/src/object/cli_shard.c b/src/object/cli_shard.c index 70fe36ee2d0..c4a0de102c7 100644 --- a/src/object/cli_shard.c +++ b/src/object/cli_shard.c @@ -1593,7 +1593,7 @@ struct obj_enum_args { daos_recx_t *eaa_recxs; daos_size_t *eaa_size; unsigned int *eaa_map_ver; - d_iov_t *csum; + d_iov_t *eaa_csum; struct dtx_epoch *epoch; daos_handle_t *th; uint64_t *enqueue_id; @@ -1799,7 +1799,7 @@ dc_enumerate_cb(tse_task_t *task, void *arg) D_GOTO(out, rc); } - rc = dc_enumerate_copy_csum(enum_args->csum, &oeo->oeo_csum_iov); + rc = dc_enumerate_copy_csum(enum_args->eaa_csum, &oeo->oeo_csum_iov); if (rc != 0) D_GOTO(out, rc); @@ -2019,7 +2019,7 @@ dc_obj_shard_list(struct dc_obj_shard *obj_shard, enum obj_rpc_opc opc, enum_args.eaa_obj = obj_shard; enum_args.eaa_size = obj_args->size; enum_args.eaa_sgl = sgl; - enum_args.csum = obj_args->csum; + enum_args.eaa_csum = obj_args->csum; enum_args.eaa_map_ver = &args->la_auxi.map_ver; enum_args.eaa_recxs = args->la_recxs; enum_args.epoch = &args->la_auxi.epoch; diff --git a/src/object/obj_enum.c b/src/object/obj_enum.c index 4175d7de907..3498b9c8991 100644 --- a/src/object/obj_enum.c +++ b/src/object/obj_enum.c @@ -1,6 +1,6 @@ /* * (C) Copyright 2018-2022 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -622,7 +622,7 @@ enum_unpack_oid(daos_key_desc_t *kds, void *data, struct io_unpack_arg { struct dc_obj_enum_unpack_io *io; dc_obj_enum_unpack_cb_t cb; - d_iov_t *csum_iov; + d_iov_t *ua_csum_iov; void *cb_arg; }; @@ -641,13 +641,13 @@ enum_obj_io_unpack_cb(daos_key_desc_t *kds, void *ptr, unsigned int size, break; case OBJ_ITER_DKEY: case OBJ_ITER_AKEY: - rc = enum_unpack_key(kds, ptr, io, unpack_arg->csum_iov, - unpack_arg->cb, unpack_arg->cb_arg); + rc = enum_unpack_key(kds, ptr, io, unpack_arg->ua_csum_iov, unpack_arg->cb, + unpack_arg->cb_arg); break; case OBJ_ITER_RECX: case OBJ_ITER_SINGLE: - rc = enum_unpack_recxs(kds, ptr, io, unpack_arg->csum_iov, - unpack_arg->cb, unpack_arg->cb_arg); + rc = enum_unpack_recxs(kds, ptr, io, unpack_arg->ua_csum_iov, unpack_arg->cb, + unpack_arg->cb_arg); break; case OBJ_ITER_OBJ_PUNCH_EPOCH: case OBJ_ITER_DKEY_EPOCH: @@ -787,7 +787,7 @@ dc_obj_enum_unpack(daos_unit_oid_t oid, daos_key_desc_t *kds, int kds_num, unpack_arg.cb = cb; unpack_arg.io = &io; unpack_arg.cb_arg = cb_arg; - unpack_arg.csum_iov = &csum_iov_in; + unpack_arg.ua_csum_iov = &csum_iov_in; rc = obj_enum_iterate(kds, sgl, kds_num, -1, enum_obj_io_unpack_cb, &unpack_arg); if (rc) diff --git a/src/object/srv_enum.c b/src/object/srv_enum.c index 4f8a4eb7531..eff8fa516a0 100644 --- a/src/object/srv_enum.c +++ b/src/object/srv_enum.c @@ -173,7 +173,7 @@ static int fill_key_csum(vos_iter_entry_t *key_ent, struct ds_obj_enum_arg *arg) { struct daos_csummer *csummer = arg->csummer; - d_iov_t *csum_iov = &arg->csum_iov; + d_iov_t *csum_iov = &arg->oea_csum_iov; struct dcs_csum_info *csum_info; int rc; @@ -455,14 +455,14 @@ csum_copy_inline(int type, vos_iter_entry_t *ent, struct ds_obj_enum_arg *arg, return rc; } - rc = fill_data_csum(new_csum_info, &arg->csum_iov); + rc = fill_data_csum(new_csum_info, &arg->oea_csum_iov); daos_csummer_free_ci(csummer, &new_csum_info); if (rc != 0) { D_ERROR("Issue filling csum data\n"); return rc; } } else { - rc = fill_data_csum(&ent->ie_csum, &arg->csum_iov); + rc = fill_data_csum(&ent->ie_csum, &arg->oea_csum_iov); if (rc != 0) { D_ERROR("Issue filling csum data\n"); return rc; diff --git a/src/object/srv_obj.c b/src/object/srv_obj.c index f8224af6183..5a8a0d03b1d 100644 --- a/src/object/srv_obj.c +++ b/src/object/srv_obj.c @@ -3655,7 +3655,7 @@ ds_obj_enum_handler(crt_rpc_t *rpc) oeo->oeo_num = enum_arg.kds_len; if (oeo->oeo_sgl.sg_iovs != NULL) oeo->oeo_size = oeo->oeo_sgl.sg_iovs[0].iov_len; - oeo->oeo_csum_iov = enum_arg.csum_iov; + oeo->oeo_csum_iov = enum_arg.oea_csum_iov; } rc = obj_enum_reply_bulk(rpc); diff --git a/src/object/srv_obj_migrate.c b/src/object/srv_obj_migrate.c index e7f0cd901a0..a1216424772 100644 --- a/src/object/srv_obj_migrate.c +++ b/src/object/srv_obj_migrate.c @@ -902,8 +902,6 @@ migrate_csum_calc(struct daos_csummer *csummer, struct migrate_one *mrone, daos_ int iod_num, d_sg_list_t *sgls, d_iov_t *csum_iov, struct dcs_iod_csums **iod_csums) { - d_iov_t tmp_csum_iov; - d_iov_t *p_csum_iov; int rc; if (daos_oclass_is_ec(&mrone->mo_oca)) { @@ -916,14 +914,12 @@ migrate_csum_calc(struct daos_csummer *csummer, struct migrate_one *mrone, daos_ D_DEBUG(DB_CSUM, DF_RB ": " DF_C_UOID_DKEY ": Using packed csums\n", DP_RB_MRO(mrone), DP_C_UOID_DKEY(mrone->mo_oid, &mrone->mo_dkey)); - /** make a copy of the iov because it will be modified while - * iterating over the csums + /* + * The packed checksum iov is consumed as iod csums are unpacked, so + * callers that need to preserve the original iov must pass a mutable copy. */ D_ASSERT(csum_iov != NULL); - tmp_csum_iov = *csum_iov; - p_csum_iov = &tmp_csum_iov; - rc = daos_csummer_alloc_iods_csums_with_packed(csummer, iods, iod_num, - p_csum_iov, iod_csums); + rc = daos_csummer_alloc_iods_csums_with_packed(csummer, iods, iod_num, csum_iov, iod_csums); if (rc != 0) DL_ERROR(rc, DF_RB ": failed to alloc iod csums", DP_RB_MRO(mrone)); @@ -956,6 +952,7 @@ migrate_fetch_update_inline(struct migrate_one *mrone, daos_handle_t oh, int rc = 0; d_iov_t *p_csum_iov = NULL; d_iov_t csum_iov = {0}; + d_iov_t packed_csum_iov = {0}; D_ASSERT(mrone->mo_iod_num <= OBJ_ENUM_UNPACK_MAX_IODS); for (i = 0; i < mrone->mo_iod_num; i++) { @@ -1012,6 +1009,9 @@ migrate_fetch_update_inline(struct migrate_one *mrone, daos_handle_t oh, &mrone->mo_oca, mrone->mo_oid.id_shard)) mrone_recx_daos2_vos(mrone, mrone->mo_iods, mrone->mo_iod_num); + if (!daos_oclass_is_ec(&mrone->mo_oca)) + packed_csum_iov = fetch ? csum_iov : mrone->mo_csum_iov; + csummer = dsc_cont2csummer(dc_obj_hdl2cont_hdl(oh)); for (i = 0, start = 0; i < mrone->mo_iod_num; i++) { daos_iod_t *iods = mrone->mo_iods; @@ -1024,6 +1024,7 @@ migrate_fetch_update_inline(struct migrate_one *mrone, daos_handle_t oh, /* skip empty record */ if (iod_cnt == 0) { D_DEBUG(DB_TRACE, DF_RB ": i %d iod_size = 0\n", DP_RB_MRO(mrone), i); + start = i + 1; continue; } @@ -1031,7 +1032,7 @@ migrate_fetch_update_inline(struct migrate_one *mrone, daos_handle_t oh, iod_cnt); rc = migrate_csum_calc(csummer, mrone, &iods[start], iod_cnt, &sgls[start], - fetch ? &csum_iov : &mrone->mo_csum_iov, &iod_csums); + &packed_csum_iov, &iod_csums); if (rc != 0) { DL_ERROR(rc, DF_RB ": error calculating checksums", DP_RB_MRO(mrone)); break; @@ -1052,8 +1053,7 @@ migrate_fetch_update_inline(struct migrate_one *mrone, daos_handle_t oh, if (iod_cnt > 0) { rc = migrate_csum_calc(csummer, mrone, &mrone->mo_iods[start], iod_cnt, - &sgls[start], fetch ? &csum_iov : &mrone->mo_csum_iov, - &iod_csums); + &sgls[start], &packed_csum_iov, &iod_csums); if (rc != 0) { DL_ERROR(rc, DF_RB ": error calculating checksums", DP_RB_MRO(mrone)); D_GOTO(out, rc); @@ -1348,6 +1348,7 @@ migrate_fetch_update_single(struct migrate_one *mrone, daos_handle_t oh, char *data; daos_size_t size; d_iov_t csum_iov = {0}; + d_iov_t packed_csum_iov = {0}; d_iov_t *p_csum_iov = NULL; struct daos_csummer *csummer = NULL; struct dcs_iod_csums *iod_csums = NULL; @@ -1385,6 +1386,10 @@ migrate_fetch_update_single(struct migrate_one *mrone, daos_handle_t oh, rc = mrone_obj_fetch(mrone, oh, sgls, mrone->mo_iods, mrone->mo_iod_num, mrone->mo_epoch, DIOF_FOR_MIGRATION, p_csum_iov); + /* migrate_csum_calc() may change csum_iov->iov_buf, so make a copy as original csum_iov + * will be freed by daos_iov_free() below. + */ + packed_csum_iov = csum_iov; if (rc == -DER_CSUM) { DL_ERROR(rc, DF_RB ": migrate dkey " DF_KEY " failed because of checksum error. " @@ -1472,8 +1477,8 @@ migrate_fetch_update_single(struct migrate_one *mrone, daos_handle_t oh, } csummer = dsc_cont2csummer(dc_obj_hdl2cont_hdl(oh)); - rc = migrate_csum_calc(csummer, mrone, mrone->mo_iods, mrone->mo_iod_num, sgls, - p_csum_iov, &iod_csums); + rc = migrate_csum_calc(csummer, mrone, mrone->mo_iods, mrone->mo_iod_num, sgls, + &packed_csum_iov, &iod_csums); if (rc != 0) { DL_ERROR(rc, DF_RB ": unable to calculate iod csums", DP_RB_MRO(mrone)); goto out; @@ -1514,6 +1519,7 @@ __migrate_fetch_update_bulk(struct migrate_one *mrone, daos_handle_t oh, daos_handle_t ioh; int sgl_cnt = 0; d_iov_t csum_iov = {0}; + d_iov_t packed_csum_iov = {0}; struct daos_csummer *csummer = NULL; struct dcs_iod_csums *iod_csums = NULL; d_iov_t *p_csum_iov = NULL; @@ -1568,6 +1574,10 @@ __migrate_fetch_update_bulk(struct migrate_one *mrone, daos_handle_t oh, } rc = mrone_obj_fetch(mrone, oh, sgls, iods, iod_num, fetch_eph, flags, p_csum_iov); + /* migrate_csum_calc() may change csum_iov->iov_buf, so make a copy as original csum_iov + * will be freed by daos_iov_free() below. + */ + packed_csum_iov = csum_iov; if (rc) { DL_ERROR(rc, DF_RB ": migrate dkey " DF_KEY " failed", DP_RB_MRO(mrone), DP_KEY(&mrone->mo_dkey)); @@ -1584,7 +1594,7 @@ __migrate_fetch_update_bulk(struct migrate_one *mrone, daos_handle_t oh, mrone_recx_daos2_vos(mrone, iods, iod_num); csummer = dsc_cont2csummer(dc_obj_hdl2cont_hdl(oh)); - rc = migrate_csum_calc(csummer, mrone, iods, iod_num, sgls, p_csum_iov, &iod_csums); + rc = migrate_csum_calc(csummer, mrone, iods, iod_num, sgls, &packed_csum_iov, &iod_csums); if (rc != 0) { DL_ERROR(rc, DF_RB ": failed to calculate iod csums", DP_RB_MRO(mrone)); D_GOTO(post, rc); diff --git a/src/placement/tests/place_obj_common.c b/src/placement/tests/place_obj_common.c index 153cbb9cf77..f30a05a40ad 100644 --- a/src/placement/tests/place_obj_common.c +++ b/src/placement/tests/place_obj_common.c @@ -924,12 +924,14 @@ bool plt_layout_with_tgts_on_same_dom_for_same_grp(struct pl_obj_layout *layout, uint32_t tgts_per_dom) { uint32_t i, j, dom, new_dom, tgt, new_tgt; + uint32_t grp_end; print_message("grp_nr %d, grp_size %d\n", layout->ol_grp_nr, layout->ol_grp_size); for (i = 0; i < layout->ol_nr; i++) { tgt = layout->ol_shards[i].po_target; dom = tgt / tgts_per_dom; - for (j = i + 1; j < roundup(i, layout->ol_grp_size); j++) { + grp_end = rounddown(i, layout->ol_grp_size) + layout->ol_grp_size; + for (j = i + 1; j < grp_end; j++) { new_tgt = layout->ol_shards[j].po_target; assert_true(new_tgt != tgt); // assert_true(tgt != -1 && new_tgt != -1);