Skip to content

Commit 4f91965

Browse files
authored
DAOS-15847 object: restore iov_len for fetch on dup-only (no-merge) SGLs (#18413)
In obj_dup_sgls_free(), when ctx->alloc_bitmaps[i] == NULL, the function skips the entire SGL with `continue`: if (!ctx->alloc_bitmaps || !ctx->alloc_bitmaps[i]) continue; This case arises when a SGL was duplicated only to strip iov_buf_len==0 entries (skip_sgl_iov returned true) but no IOVs were merged into allocated buffers. During construction (second pass of obj_sgls_dup), non-merged IOVs are copied as: *iov_dup = *iov; So iov_dup->iov_buf == iov->iov_buf (same pointer). The lower layer writes fetch data into iov_dup->iov_buf and updates iov_dup->iov_len to reflect actual bytes read. Because obj_dup_sgls_free skips such SGLs, iov->iov_len in the *original* SGL is never updated. After api_args->sgls is restored to orr_usgls, the caller sees stale pre-fetch iov_len values even though the data is in the correct buffers. Signed-off-by: Xuezhao Liu <xuezhao.liu@hpe.com>
1 parent 2af3f8d commit 4f91965

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

src/object/cli_obj.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4943,8 +4943,26 @@ obj_dup_sgls_free(struct obj_auxi_args *obj_auxi)
49434943
uint32_t dup_data_len = 0;
49444944
char *dup_buf;
49454945

4946-
if (!ctx->alloc_bitmaps || !ctx->alloc_bitmaps[i])
4946+
if (!ctx->alloc_bitmaps || !ctx->alloc_bitmaps[i]) {
4947+
/* SGL was duplicated (e.g. to strip zero-buf-len
4948+
* entries) but has no merged/allocated buffers.
4949+
* Dup IOVs share the same iov_buf pointers as the
4950+
* originals, so fetch data is already in place.
4951+
* Copy iov_len back so the caller sees actual bytes
4952+
* read, and update sg_nr_out accordingly.
4953+
*/
4954+
uint32_t dup_idx = 0;
4955+
4956+
for (j = 0; j < sg_orig->sg_nr && dup_idx < sg_dup->sg_nr_out;
4957+
j++) {
4958+
iov = &sg_orig->sg_iovs[j];
4959+
if (skip_sgl_iov(false, iov))
4960+
continue;
4961+
iov->iov_len = sg_dup->sg_iovs[dup_idx++].iov_len;
4962+
}
4963+
sg_orig->sg_nr_out = j;
49474964
continue;
4965+
}
49484966

49494967
D_ASSERT(ctx->merged_bitmaps[i] != NULL);
49504968
for (j = 0; j < sg_orig->sg_nr && dup_sg_idx < sg_dup->sg_nr_out; j++) {
@@ -4989,7 +5007,6 @@ obj_dup_sgls_free(struct obj_auxi_args *obj_auxi)
49895007
D_FREE(ctx);
49905008
obj_auxi->rw_args.merge_ctx = NULL;
49915009
api_args = dc_task_get_args(obj_auxi->obj_task);
4992-
api_args = dc_task_get_args(obj_auxi->obj_task);
49935010
api_args->sgls = obj_auxi->reasb_req.orr_usgls;
49945011
}
49955012

0 commit comments

Comments
 (0)