Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/client/kv/dc_kv.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* (C) Copyright 2017-2024 Intel Corporation.
* (C) Copyright 2026 Hewlett Packard Enterprise Development LP
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*/
Expand Down Expand Up @@ -94,12 +95,19 @@ kv_hdl2ptr(daos_handle_t oh)

daos_handle_t daos_kv2objhandle(daos_handle_t kv_oh)
{
struct dc_kv *dk = kv_hdl2ptr(kv_oh);
struct dc_kv *dk;
daos_handle_t oh;

if (dk)
return dk->daos_oh;
dk = kv_hdl2ptr(kv_oh);
if (dk == NULL) {
oh = DAOS_HDL_INVAL;
goto out;
}
oh = dk->daos_oh;
kv_decref(dk);

return DAOS_HDL_INVAL;
out:
return oh;
}

static void
Expand Down
61 changes: 53 additions & 8 deletions src/tests/suite/daos_kv.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* (C) Copyright 2016-2022 Intel Corporation.
* (C) Copyright 2026 Hewlett Packard Enterprise Development LP
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*/
Expand All @@ -10,6 +11,7 @@
*/
#include <daos.h>
#include <daos_kv.h>
#include <daos/kv.h>
#include "daos_test.h"

#if D_HAS_WARNING(4, "-Wframe-larger-than")
Expand Down Expand Up @@ -352,15 +354,58 @@ kv_cond_ops(void **state)
print_message("all good\n");
} /* End simple_put_get */

static void
kv_obj_handle(void **state)
{
test_arg_t *arg = *state;
daos_obj_id_t oid;
daos_handle_t kv_oh;
daos_handle_t oh;
int rc;
int i;

/** invalid handle must return DAOS_HDL_INVAL */
print_message("Getting obj handle from invalid KV handle\n");
oh = daos_kv2objhandle(DAOS_HDL_INVAL);
assert_true(daos_handle_is_inval(oh));

oid = daos_test_oid_gen(arg->coh, OC_SX, type, 0, arg->myrank);
rc = daos_kv_open(arg->coh, oid, DAOS_OO_RW, &kv_oh, NULL);
assert_rc_equal(rc, 0);

/** valid handle must return a valid object handle */
print_message("Getting obj handle from valid KV handle\n");
oh = daos_kv2objhandle(kv_oh);
assert_true(daos_handle_is_valid(oh));

/**
* Call multiple times: each call must release the lookup reference so
* no reference leak accumulates (regression for DAOS-19018).
* When built with ASAN/LeakSanitizer, any leaked dc_kv reference will
* be reported here.
*/
print_message("Calling daos_kv2objhandle() repeatedly\n");
for (i = 0; i < 10; i++) {
oh = daos_kv2objhandle(kv_oh);
assert_true(daos_handle_is_valid(oh));
}

/** KV must be closeable after repeated calls */
print_message("Closing KV handle\n");
rc = daos_kv_close(kv_oh, NULL);
assert_rc_equal(rc, 0);

print_message("all good\n");
}

static const struct CMUnitTest kv_tests[] = {
{"KV: Object Put/GET (blocking)",
simple_put_get, async_disable, NULL},
{"KV: Object Put/GET with daos_ofeat_t flag(blocking)",
simple_put_get_old, async_disable, NULL},
{"KV: Object Put/GET (non-blocking)",
simple_put_get, async_enable, NULL},
{"KV: Object Conditional Ops (blocking)",
kv_cond_ops, async_disable, NULL},
{"KV: Object Put/GET (blocking)", simple_put_get, async_disable, NULL},
{"KV: Object Put/GET with daos_ofeat_t flag(blocking)", simple_put_get_old, async_disable,
NULL},
{"KV: Object Put/GET (non-blocking)", simple_put_get, async_enable, NULL},
{"KV: Object Conditional Ops (blocking)", kv_cond_ops, async_disable, NULL},
{"KV: daos_kv2objhandle() correctness and reference leak (DAOS-19018)", kv_obj_handle,
async_disable, NULL},
};

int
Expand Down
Loading