@@ -66,11 +66,9 @@ static struct nvme_host *default_host;
6666static void __nvme_free_host (nvme_host_t h );
6767static void __nvme_free_ctrl (nvme_ctrl_t c );
6868static 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 );
7170static 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 );
7472static int nvme_ctrl_scan_namespace (nvme_root_t r , struct nvme_ctrl * c ,
7573 char * name );
7674static 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+
222282int 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
22732319static 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
28982944static 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