File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -39,6 +39,11 @@ nvme_root_t nvme_mi_create_root(FILE *fp, int log_level)
3939
4040void nvme_mi_free_root (nvme_root_t root )
4141{
42+ nvme_mi_ep_t ep , tmp ;
43+
44+ nvme_mi_for_each_endpoint_safe (root , ep , tmp )
45+ nvme_mi_close (ep );
46+
4247 free (root );
4348}
4449
@@ -50,6 +55,8 @@ struct nvme_mi_ep *nvme_mi_init_ep(nvme_root_t root)
5055 list_node_init (& ep -> root_entry );
5156 ep -> root = root ;
5257
58+ list_add (& root -> endpoints , & ep -> root_entry );
59+
5360 return ep ;
5461}
5562
Original file line number Diff line number Diff line change @@ -317,6 +317,18 @@ nvme_mi_ep_t nvme_mi_next_endpoint(nvme_root_t m, nvme_mi_ep_t e);
317317 for (e = nvme_mi_first_endpoint(m); e != NULL; \
318318 e = nvme_mi_next_endpoint(m, e))
319319
320+ /**
321+ * nvme_mi_for_each_endpoint_safe - Iterator for NVMe-MI endpoints, allowing
322+ * deletion during traversal
323+ * @m: &nvme_root_t containing endpoints
324+ * @e: &nvme_mi_ep_t object, set on each iteration
325+ * @_e: &nvme_mi_ep_t object used as temporary storage
326+ */
327+ #define nvme_mi_for_each_endpoint_safe (m , e , _e ) \
328+ for (e = nvme_mi_first_endpoint(m), _e = nvme_mi_next_endpoint(m, e); \
329+ e != NULL; \
330+ e = _e, _e = nvme_mi_next_endpoint(m, e))
331+
320332struct nvme_mi_ctrl ;
321333
322334/**
Original file line number Diff line number Diff line change @@ -121,6 +121,37 @@ nvme_mi_ep_t nvme_mi_open_test(nvme_root_t root)
121121 return ep ;
122122}
123123
124+ unsigned int count_root_eps (nvme_root_t root )
125+ {
126+ unsigned int i = 0 ;
127+ nvme_mi_ep_t ep ;
128+
129+ nvme_mi_for_each_endpoint (root , ep )
130+ i ++ ;
131+
132+ return i ;
133+ }
134+
135+ /* test that the root->endpoints list is updated on endpoint
136+ * creation/destruction */
137+ static void test_endpoint_lifetime (nvme_mi_ep_t ep )
138+ {
139+ nvme_root_t root = ep -> root ;
140+ unsigned int count ;
141+ nvme_mi_ep_t ep2 ;
142+
143+ count = count_root_eps (root );
144+ assert (count == 1 );
145+
146+ ep2 = nvme_mi_open_test (root );
147+ count = count_root_eps (root );
148+ assert (count == 2 );
149+
150+ nvme_mi_close (ep2 );
151+ count = count_root_eps (root );
152+ assert (count == 1 );
153+ }
154+
124155/* test: basic read MI datastructure command */
125156static int test_read_mi_data_cb (struct nvme_mi_ep * ep ,
126157 struct nvme_mi_req * req ,
@@ -357,6 +388,7 @@ struct test {
357388 const char * name ;
358389 void (* fn )(nvme_mi_ep_t );
359390} tests [] = {
391+ DEFINE_TEST (endpoint_lifetime ),
360392 DEFINE_TEST (read_mi_data ),
361393 DEFINE_TEST (transport_fail ),
362394 DEFINE_TEST (transport_describe ),
You can’t perform that action at this time.
0 commit comments