Skip to content

Commit d64a019

Browse files
committed
tree: filter tree after scan has completed
The tree structure is not completely connected when the filter function is called. E.g. a controller might not yet have the namespace object associated. Thus, run the filter function after it has fully created and updated, allowing the filter function to inspect the objects with everything correctly setup. Signed-off-by: Daniel Wagner <[email protected]>
1 parent 846d61c commit d64a019

1 file changed

Lines changed: 78 additions & 37 deletions

File tree

src/nvme/tree.c

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,9 @@ static struct nvme_host *default_host;
6666
static void __nvme_free_host(nvme_host_t h);
6767
static void __nvme_free_ctrl(nvme_ctrl_t c);
6868
static int nvme_subsystem_scan_namespace(nvme_root_t r,
69-
struct nvme_subsystem *s, char *name,
70-
nvme_scan_filter_t f, void *f_args);
69+
struct nvme_subsystem *s, char *name);
7170
static int nvme_init_subsystem(nvme_subsystem_t s, const char *name);
72-
static int nvme_scan_subsystem(nvme_root_t r, const char *name,
73-
nvme_scan_filter_t f, void *f_args);
71+
static int nvme_scan_subsystem(nvme_root_t r, const char *name);
7472
static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
7573
char *name);
7674
static int nvme_ctrl_scan_path(nvme_root_t r, struct nvme_ctrl *c, char *name);
@@ -219,6 +217,68 @@ nvme_host_t nvme_default_host(nvme_root_t r)
219217
return h;
220218
}
221219

220+
static void nvme_filter_subsystem(nvme_root_t r, nvme_subsystem_t s,
221+
nvme_scan_filter_t f, void *f_args)
222+
{
223+
if (f(s, NULL, NULL, f_args))
224+
return;
225+
226+
nvme_msg(r, LOG_DEBUG, "filter out subsystem %s\n",
227+
nvme_subsystem_get_name(s));
228+
nvme_free_subsystem(s);
229+
}
230+
231+
static void nvme_filter_ns(nvme_root_t r, nvme_ns_t n,
232+
nvme_scan_filter_t f, void *f_args)
233+
{
234+
if (f(NULL, NULL, n, f_args))
235+
return;
236+
237+
nvme_msg(r, LOG_DEBUG, "filter out namespace %s\n",
238+
nvme_ns_get_name(n));
239+
nvme_free_ns(n);
240+
}
241+
242+
static void nvme_filter_ctrl(nvme_root_t r, nvme_ctrl_t c,
243+
nvme_scan_filter_t f, void *f_args)
244+
{
245+
if (f(NULL, c, NULL, f_args))
246+
return;
247+
248+
nvme_msg(r, LOG_DEBUG, "filter out controller %s\n",
249+
nvme_ctrl_get_name(c));
250+
nvme_free_ctrl(c);
251+
}
252+
253+
static void nvme_filter_tree(nvme_root_t r, nvme_scan_filter_t f, void *f_args)
254+
{
255+
nvme_host_t h, _h;
256+
nvme_subsystem_t s, _s;
257+
nvme_ns_t n, _n;
258+
nvme_path_t p, _p;
259+
nvme_ctrl_t c, _c;
260+
261+
if (!f)
262+
return;
263+
264+
nvme_for_each_host_safe(r, h, _h) {
265+
nvme_for_each_subsystem_safe(h, s, _s) {
266+
nvme_subsystem_for_each_ctrl_safe(s, c, _c)
267+
nvme_filter_ctrl(r, c, f, f_args);
268+
269+
nvme_subsystem_for_each_ns_safe(s, n, _n) {
270+
nvme_namespace_for_each_path_safe(n, p, _p) {
271+
nvme_filter_ctrl(r, nvme_path_get_ctrl(p),
272+
f, f_args);
273+
}
274+
nvme_filter_ns(r, n, f, f_args);
275+
}
276+
277+
nvme_filter_subsystem(r, s, f, f_args);
278+
}
279+
}
280+
}
281+
222282
int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f, void *f_args)
223283
{
224284
_cleanup_dirents_ struct dirents subsys = {}, ctrls = {};
@@ -241,11 +301,6 @@ int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f, void *f_args)
241301
ctrls.ents[i]->d_name, strerror(errno));
242302
continue;
243303
}
244-
if ((f) && !f(NULL, c, NULL, f_args)) {
245-
nvme_msg(r, LOG_DEBUG, "filter out controller %s\n",
246-
ctrls.ents[i]->d_name);
247-
nvme_free_ctrl(c);
248-
}
249304
}
250305

251306
subsys.num = nvme_scan_subsystems(&subsys.ents);
@@ -256,15 +311,20 @@ int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f, void *f_args)
256311
}
257312

258313
for (i = 0; i < subsys.num; i++) {
259-
ret = nvme_scan_subsystem(
260-
r, subsys.ents[i]->d_name, f, f_args);
314+
ret = nvme_scan_subsystem(r, subsys.ents[i]->d_name);
261315
if (ret < 0) {
262316
nvme_msg(r, LOG_DEBUG,
263317
"failed to scan subsystem %s: %s\n",
264318
subsys.ents[i]->d_name, strerror(errno));
265319
}
266320
}
267321

322+
/*
323+
* Filter the tree after it has been fully populated and
324+
* updated
325+
*/
326+
nvme_filter_tree(r, f, f_args);
327+
268328
return 0;
269329
}
270330

@@ -750,8 +810,7 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn,
750810
return h;
751811
}
752812

753-
static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
754-
nvme_scan_filter_t f, void *f_args)
813+
static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s)
755814
{
756815
_cleanup_dirents_ struct dirents namespaces = {};
757816
int i, ret;
@@ -772,7 +831,7 @@ static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
772831

773832
for (i = 0; i < namespaces.num; i++) {
774833
ret = nvme_subsystem_scan_namespace(r, s,
775-
namespaces.ents[i]->d_name, f, f_args);
834+
namespaces.ents[i]->d_name);
776835
if (ret < 0)
777836
nvme_msg(r, LOG_DEBUG,
778837
"failed to scan namespace %s: %s\n",
@@ -810,20 +869,7 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name)
810869
return 0;
811870
}
812871

813-
static bool __nvme_scan_subsystem(struct nvme_root *r, nvme_subsystem_t s,
814-
nvme_scan_filter_t f, void *f_args)
815-
{
816-
if (f && !f(s, NULL, NULL, f_args)) {
817-
nvme_msg(r, LOG_DEBUG, "filter out subsystem %s\n", s->name);
818-
__nvme_free_subsystem(s);
819-
return false;
820-
}
821-
nvme_subsystem_scan_namespaces(r, s, f, f_args);
822-
return true;
823-
}
824-
825-
static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
826-
nvme_scan_filter_t f, void *f_args)
872+
static int nvme_scan_subsystem(struct nvme_root *r, const char *name)
827873
{
828874
struct nvme_subsystem *s = NULL, *_s;
829875
_cleanup_free_ char *path = NULL, *subsysnqn = NULL;
@@ -851,7 +897,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
851897
continue;
852898
if (strcmp(_s->name, name))
853899
continue;
854-
if (!__nvme_scan_subsystem(r, _s, f, f_args)) {
900+
if (!nvme_subsystem_scan_namespaces(r, _s)) {
855901
errno = EINVAL;
856902
return -1;
857903
}
@@ -872,7 +918,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
872918
errno = ENOMEM;
873919
return -1;
874920
}
875-
if (!__nvme_scan_subsystem(r, s, f, f_args)) {
921+
if (!nvme_subsystem_scan_namespaces(r, s)) {
876922
errno = EINVAL;
877923
return -1;
878924
}
@@ -2267,7 +2313,7 @@ void nvme_rescan_ctrl(struct nvme_ctrl *c)
22672313
return;
22682314
nvme_ctrl_scan_namespaces(r, c);
22692315
nvme_ctrl_scan_paths(r, c);
2270-
nvme_subsystem_scan_namespaces(r, c->s, NULL, NULL);
2316+
nvme_subsystem_scan_namespaces(r, c->s);
22712317
}
22722318

22732319
static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count,
@@ -2896,7 +2942,7 @@ static void nvme_subsystem_set_ns_path(nvme_subsystem_t s, nvme_ns_t n)
28962942
}
28972943

28982944
static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
2899-
char *name, nvme_scan_filter_t f, void *f_args)
2945+
char *name)
29002946
{
29012947
struct nvme_ns *n, *_n, *__n;
29022948

@@ -2907,11 +2953,6 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
29072953
nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name);
29082954
return -1;
29092955
}
2910-
if (f && !f(NULL, NULL, n, f_args)) {
2911-
nvme_msg(r, LOG_DEBUG, "filter out namespace %s\n", name);
2912-
__nvme_free_ns(n);
2913-
return 0;
2914-
}
29152956
nvme_subsystem_for_each_ns_safe(s, _n, __n) {
29162957
struct nvme_path *p, *_p;
29172958

0 commit comments

Comments
 (0)