Skip to content

Commit e9c310a

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 9562713 commit e9c310a

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

@@ -752,8 +812,7 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn,
752812
return h;
753813
}
754814

755-
static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
756-
nvme_scan_filter_t f, void *f_args)
815+
static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s)
757816
{
758817
_cleanup_dirents_ struct dirents namespaces = {};
759818
int i, ret;
@@ -774,7 +833,7 @@ static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
774833

775834
for (i = 0; i < namespaces.num; i++) {
776835
ret = nvme_subsystem_scan_namespace(r, s,
777-
namespaces.ents[i]->d_name, f, f_args);
836+
namespaces.ents[i]->d_name);
778837
if (ret < 0)
779838
nvme_msg(r, LOG_DEBUG,
780839
"failed to scan namespace %s: %s\n",
@@ -812,20 +871,7 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name)
812871
return 0;
813872
}
814873

815-
static bool __nvme_scan_subsystem(struct nvme_root *r, nvme_subsystem_t s,
816-
nvme_scan_filter_t f, void *f_args)
817-
{
818-
if (f && !f(s, NULL, NULL, f_args)) {
819-
nvme_msg(r, LOG_DEBUG, "filter out subsystem %s\n", s->name);
820-
__nvme_free_subsystem(s);
821-
return false;
822-
}
823-
nvme_subsystem_scan_namespaces(r, s, f, f_args);
824-
return true;
825-
}
826-
827-
static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
828-
nvme_scan_filter_t f, void *f_args)
874+
static int nvme_scan_subsystem(struct nvme_root *r, const char *name)
829875
{
830876
struct nvme_subsystem *s = NULL, *_s;
831877
_cleanup_free_ char *path = NULL, *subsysnqn = NULL;
@@ -853,7 +899,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
853899
continue;
854900
if (strcmp(_s->name, name))
855901
continue;
856-
if (!__nvme_scan_subsystem(r, _s, f, f_args)) {
902+
if (!nvme_subsystem_scan_namespaces(r, _s)) {
857903
errno = EINVAL;
858904
return -1;
859905
}
@@ -874,7 +920,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
874920
errno = ENOMEM;
875921
return -1;
876922
}
877-
if (!__nvme_scan_subsystem(r, s, f, f_args)) {
923+
if (!nvme_subsystem_scan_namespaces(r, s)) {
878924
errno = EINVAL;
879925
return -1;
880926
}
@@ -2276,7 +2322,7 @@ void nvme_rescan_ctrl(struct nvme_ctrl *c)
22762322
return;
22772323
nvme_ctrl_scan_namespaces(r, c);
22782324
nvme_ctrl_scan_paths(r, c);
2279-
nvme_subsystem_scan_namespaces(r, c->s, NULL, NULL);
2325+
nvme_subsystem_scan_namespaces(r, c->s);
22802326
}
22812327

22822328
static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count,
@@ -2983,7 +3029,7 @@ static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
29833029
}
29843030

29853031
static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
2986-
char *name, nvme_scan_filter_t f, void *f_args)
3032+
char *name)
29873033
{
29883034
struct nvme_ns *n, *_n, *__n;
29893035

@@ -2994,11 +3040,6 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
29943040
nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name);
29953041
return -1;
29963042
}
2997-
if (f && !f(NULL, NULL, n, f_args)) {
2998-
nvme_msg(r, LOG_DEBUG, "filter out namespace %s\n", name);
2999-
__nvme_free_ns(n);
3000-
return 0;
3001-
}
30023043
nvme_subsystem_for_each_ns_safe(s, _n, __n) {
30033044
struct nvme_path *p, *_p;
30043045

0 commit comments

Comments
 (0)