Skip to content

Commit c6601cf

Browse files
committed
tree: handle error when trying to get transport handle
nvme_ns_get_transport_handle is creating a handle on demand, which can fail. Thus we need to propagate this error case and not blindly access the handle later and cause a NULL pointer access. Signed-off-by: Daniel Wagner <[email protected]>
1 parent 09049e3 commit c6601cf

4 files changed

Lines changed: 85 additions & 23 deletions

File tree

libnvme/src/nvme/private.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ static inline __u16 nvmf_exat_size(size_t val_len)
739739
/**
740740
* nvme_ns_get_transport_handle() - Get associated transport handle
741741
* @n: Namespace instance
742+
* @hdl: Transport handle
742743
*
743744
* libnvme will open() the file (if not already opened) and keep
744745
* an internal copy of the link handle. Following calls to
@@ -747,9 +748,10 @@ static inline __u16 nvmf_exat_size(size_t val_len)
747748
* remain cached until the ns object is deleted or
748749
* nvme_ns_release_transport_handle() is called.
749750
*
750-
* Return: Link handle with @n or NULL
751+
* Return: On success 0, else error code.
751752
*/
752-
struct nvme_transport_handle *nvme_ns_get_transport_handle(nvme_ns_t n);
753+
int nvme_ns_get_transport_handle(nvme_ns_t n,
754+
struct nvme_transport_handle **hdl);
753755

754756
/**
755757
* nvme_ns_release_transport_handle() - Free transport handle from ns object

libnvme/src/nvme/tree.c

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,19 +2299,24 @@ static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count,
22992299
return 0;
23002300
}
23012301

2302-
struct nvme_transport_handle *nvme_ns_get_transport_handle(nvme_ns_t n)
2302+
int nvme_ns_get_transport_handle(nvme_ns_t n,
2303+
struct nvme_transport_handle **hdl)
23032304
{
2304-
if (!n->hdl) {
2305-
int err;
2305+
int err;
23062306

2307-
err = nvme_open(n->ctx, n->name, &n->hdl);
2308-
if (err)
2309-
nvme_msg(n->ctx, LOG_ERR,
2310-
"Failed to open ns %s, error %d\n",
2311-
n->name, err);
2307+
if (n->hdl)
2308+
goto valid;
2309+
2310+
err = nvme_open(n->ctx, n->name, &n->hdl);
2311+
if (err) {
2312+
nvme_msg(n->ctx, LOG_ERR, "Failed to open ns %s, error %d\n",
2313+
n->name, err);
2314+
return err;
23122315
}
23132316

2314-
return n->hdl;
2317+
valid:
2318+
*hdl = n->hdl;
2319+
return 0;
23152320
}
23162321

23172322
void nvme_ns_release_transport_handle(nvme_ns_t n)
@@ -2415,28 +2420,43 @@ void nvme_ns_get_uuid(nvme_ns_t n, unsigned char out[NVME_UUID_LEN])
24152420

24162421
int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns)
24172422
{
2418-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2423+
struct nvme_transport_handle *hdl;
24192424
struct nvme_passthru_cmd cmd;
2425+
int err;
2426+
2427+
err = nvme_ns_get_transport_handle(n, &hdl);
2428+
if (err)
2429+
return err;
24202430

24212431
nvme_init_identify_ns(&cmd, nvme_ns_get_nsid(n), ns);
24222432
return nvme_submit_admin_passthru(hdl, &cmd);
24232433
}
24242434

24252435
int nvme_ns_identify_descs(nvme_ns_t n, struct nvme_ns_id_desc *descs)
24262436
{
2427-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2437+
struct nvme_transport_handle *hdl;
24282438
struct nvme_passthru_cmd cmd;
2439+
int err;
2440+
2441+
err = nvme_ns_get_transport_handle(n, &hdl);
2442+
if (err)
2443+
return err;
24292444

24302445
nvme_init_identify_ns_descs_list(&cmd, nvme_ns_get_nsid(n), descs);
24312446
return nvme_submit_admin_passthru(hdl, &cmd);
24322447
}
24332448

24342449
int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count)
24352450
{
2436-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2451+
struct nvme_transport_handle *hdl;
24372452
struct nvme_passthru_cmd cmd;
24382453
__u64 slba;
24392454
__u16 nlb;
2455+
int err;
2456+
2457+
err = nvme_ns_get_transport_handle(n, &hdl);
2458+
if (err)
2459+
return err;
24402460

24412461
if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb))
24422462
return -1;
@@ -2449,10 +2469,15 @@ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count)
24492469

24502470
int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count)
24512471
{
2452-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2472+
struct nvme_transport_handle *hdl;
24532473
struct nvme_passthru_cmd cmd;
24542474
__u64 slba;
24552475
__u16 nlb;
2476+
int err;
2477+
2478+
err = nvme_ns_get_transport_handle(n, &hdl);
2479+
if (err)
2480+
return err;
24562481

24572482
if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb))
24582483
return -1;
@@ -2465,10 +2490,15 @@ int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count)
24652490

24662491
int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count)
24672492
{
2468-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2493+
struct nvme_transport_handle *hdl;
24692494
struct nvme_passthru_cmd cmd;
24702495
__u64 slba;
24712496
__u16 nlb;
2497+
int err;
2498+
2499+
err = nvme_ns_get_transport_handle(n, &hdl);
2500+
if (err)
2501+
return err;
24722502

24732503
if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb))
24742504
return -1;
@@ -2480,10 +2510,15 @@ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count)
24802510

24812511
int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count)
24822512
{
2483-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2513+
struct nvme_transport_handle *hdl;
24842514
struct nvme_passthru_cmd cmd;
24852515
__u64 slba;
24862516
__u16 nlb;
2517+
int err;
2518+
2519+
err = nvme_ns_get_transport_handle(n, &hdl);
2520+
if (err)
2521+
return err;
24872522

24882523
if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb))
24892524
return -1;
@@ -2496,10 +2531,15 @@ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count)
24962531

24972532
int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count)
24982533
{
2499-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2534+
struct nvme_transport_handle *hdl;
25002535
struct nvme_passthru_cmd cmd;
25012536
__u64 slba;
25022537
__u16 nlb;
2538+
int err;
2539+
2540+
err = nvme_ns_get_transport_handle(n, &hdl);
2541+
if (err)
2542+
return err;
25032543

25042544
if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb))
25052545
return -1;
@@ -2512,10 +2552,15 @@ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count)
25122552

25132553
int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count)
25142554
{
2515-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
2555+
struct nvme_transport_handle *hdl;
25162556
struct nvme_passthru_cmd cmd;
25172557
__u64 slba;
25182558
__u16 nlb;
2559+
int err;
2560+
2561+
err = nvme_ns_get_transport_handle(n, &hdl);
2562+
if (err)
2563+
return err;
25192564

25202565
if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb))
25212566
return -1;
@@ -2528,8 +2573,14 @@ int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count)
25282573

25292574
int nvme_ns_flush(nvme_ns_t n)
25302575
{
2531-
return nvme_flush(nvme_ns_get_transport_handle(n),
2532-
nvme_ns_get_nsid(n));
2576+
struct nvme_transport_handle *hdl;
2577+
int err;
2578+
2579+
err = nvme_ns_get_transport_handle(n, &hdl);
2580+
if (err)
2581+
return err;
2582+
2583+
return nvme_flush(hdl, nvme_ns_get_nsid(n));
25332584
}
25342585

25352586
static int nvme_strtou64(const char *str, void *res)

libnvme/test/test.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,17 @@ static int test_ctrl(nvme_ctrl_t c)
324324
static int test_namespace(nvme_ns_t n)
325325
{
326326
int ret, nsid = nvme_ns_get_nsid(n);
327-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
327+
struct nvme_transport_handle *hdl;
328328
struct nvme_passthru_cmd cmd;
329329
struct nvme_id_ns ns = { 0 }, allocated = { 0 };
330330
struct nvme_ns_id_desc *descs;
331331
__u64 result = 0;
332332
__u8 flbas;
333333

334+
ret = nvme_ns_get_transport_handle(n, &hdl);
335+
if (ret)
336+
return ret;
337+
334338
ret = nvme_ns_identify(n, &ns);
335339
if (ret)
336340
return ret;

libnvme/test/zns.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@
2424

2525
static void show_zns_properties(nvme_ns_t n)
2626
{
27-
struct nvme_transport_handle *hdl = nvme_ns_get_transport_handle(n);
27+
struct nvme_transport_handle *hdl;
2828
struct nvme_passthru_cmd cmd;
2929
struct nvme_zns_id_ns zns_ns;
3030
struct nvme_zns_id_ctrl zns_ctrl;
3131
struct nvme_zone_report *zr;
32+
int err;
33+
34+
err = nvme_ns_get_transport_handle(n, &hdl);
35+
if (err)
36+
return;
3237

3338
zr = calloc(1, 0x1000);
3439
if (!zr)

0 commit comments

Comments
 (0)