@@ -127,7 +127,7 @@ static u32 nvmet_max_nsid(struct nvmet_subsys *subsys)
127127 unsigned long idx ;
128128 u32 nsid = 0 ;
129129
130- xa_for_each (& subsys -> namespaces , idx , cur )
130+ nvmet_for_each_enabled_ns (& subsys -> namespaces , idx , cur )
131131 nsid = cur -> nsid ;
132132
133133 return nsid ;
@@ -441,11 +441,14 @@ u16 nvmet_req_find_ns(struct nvmet_req *req)
441441 struct nvmet_subsys * subsys = nvmet_req_subsys (req );
442442
443443 req -> ns = xa_load (& subsys -> namespaces , nsid );
444- if (unlikely (!req -> ns )) {
444+ if (unlikely (!req -> ns || ! req -> ns -> enabled )) {
445445 req -> error_loc = offsetof(struct nvme_common_command , nsid );
446- if (nvmet_subsys_nsid_exists (subsys , nsid ))
447- return NVME_SC_INTERNAL_PATH_ERROR ;
448- return NVME_SC_INVALID_NS | NVME_STATUS_DNR ;
446+ if (!req -> ns ) /* ns doesn't exist! */
447+ return NVME_SC_INVALID_NS | NVME_STATUS_DNR ;
448+
449+ /* ns exists but it's disabled */
450+ req -> ns = NULL ;
451+ return NVME_SC_INTERNAL_PATH_ERROR ;
449452 }
450453
451454 percpu_ref_get (& req -> ns -> ref );
@@ -583,8 +586,6 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
583586 goto out_unlock ;
584587
585588 ret = - EMFILE ;
586- if (subsys -> nr_namespaces == NVMET_MAX_NAMESPACES )
587- goto out_unlock ;
588589
589590 ret = nvmet_bdev_ns_enable (ns );
590591 if (ret == - ENOTBLK )
@@ -599,38 +600,19 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
599600 list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
600601 nvmet_p2pmem_ns_add_p2p (ctrl , ns );
601602
602- ret = percpu_ref_init (& ns -> ref , nvmet_destroy_namespace ,
603- 0 , GFP_KERNEL );
604- if (ret )
605- goto out_dev_put ;
606-
607- if (ns -> nsid > subsys -> max_nsid )
608- subsys -> max_nsid = ns -> nsid ;
609-
610- ret = xa_insert (& subsys -> namespaces , ns -> nsid , ns , GFP_KERNEL );
611- if (ret )
612- goto out_restore_subsys_maxnsid ;
613-
614603 if (ns -> pr .enable ) {
615604 ret = nvmet_pr_init_ns (ns );
616605 if (ret )
617- goto out_remove_from_subsys ;
606+ goto out_dev_put ;
618607 }
619608
620- subsys -> nr_namespaces ++ ;
621-
622609 nvmet_ns_changed (subsys , ns -> nsid );
623610 ns -> enabled = true;
611+ xa_set_mark (& subsys -> namespaces , ns -> nsid , NVMET_NS_ENABLED );
624612 ret = 0 ;
625613out_unlock :
626614 mutex_unlock (& subsys -> lock );
627615 return ret ;
628-
629- out_remove_from_subsys :
630- xa_erase (& subsys -> namespaces , ns -> nsid );
631- out_restore_subsys_maxnsid :
632- subsys -> max_nsid = nvmet_max_nsid (subsys );
633- percpu_ref_exit (& ns -> ref );
634616out_dev_put :
635617 list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
636618 pci_dev_put (radix_tree_delete (& ctrl -> p2p_ns_map , ns -> nsid ));
@@ -649,15 +631,37 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
649631 goto out_unlock ;
650632
651633 ns -> enabled = false;
652- xa_erase (& ns -> subsys -> namespaces , ns -> nsid );
653- if (ns -> nsid == subsys -> max_nsid )
654- subsys -> max_nsid = nvmet_max_nsid (subsys );
634+ xa_clear_mark (& subsys -> namespaces , ns -> nsid , NVMET_NS_ENABLED );
655635
656636 list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
657637 pci_dev_put (radix_tree_delete (& ctrl -> p2p_ns_map , ns -> nsid ));
658638
659639 mutex_unlock (& subsys -> lock );
660640
641+ if (ns -> pr .enable )
642+ nvmet_pr_exit_ns (ns );
643+
644+ mutex_lock (& subsys -> lock );
645+ nvmet_ns_changed (subsys , ns -> nsid );
646+ nvmet_ns_dev_disable (ns );
647+ out_unlock :
648+ mutex_unlock (& subsys -> lock );
649+ }
650+
651+ void nvmet_ns_free (struct nvmet_ns * ns )
652+ {
653+ struct nvmet_subsys * subsys = ns -> subsys ;
654+
655+ nvmet_ns_disable (ns );
656+
657+ mutex_lock (& subsys -> lock );
658+
659+ xa_erase (& subsys -> namespaces , ns -> nsid );
660+ if (ns -> nsid == subsys -> max_nsid )
661+ subsys -> max_nsid = nvmet_max_nsid (subsys );
662+
663+ mutex_unlock (& subsys -> lock );
664+
661665 /*
662666 * Now that we removed the namespaces from the lookup list, we
663667 * can kill the per_cpu ref and wait for any remaining references
@@ -671,21 +675,9 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
671675 wait_for_completion (& ns -> disable_done );
672676 percpu_ref_exit (& ns -> ref );
673677
674- if (ns -> pr .enable )
675- nvmet_pr_exit_ns (ns );
676-
677678 mutex_lock (& subsys -> lock );
678-
679679 subsys -> nr_namespaces -- ;
680- nvmet_ns_changed (subsys , ns -> nsid );
681- nvmet_ns_dev_disable (ns );
682- out_unlock :
683680 mutex_unlock (& subsys -> lock );
684- }
685-
686- void nvmet_ns_free (struct nvmet_ns * ns )
687- {
688- nvmet_ns_disable (ns );
689681
690682 down_write (& nvmet_ana_sem );
691683 nvmet_ana_group_enabled [ns -> anagrpid ]-- ;
@@ -699,15 +691,33 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)
699691{
700692 struct nvmet_ns * ns ;
701693
694+ mutex_lock (& subsys -> lock );
695+
696+ if (subsys -> nr_namespaces == NVMET_MAX_NAMESPACES )
697+ goto out_unlock ;
698+
702699 ns = kzalloc (sizeof (* ns ), GFP_KERNEL );
703700 if (!ns )
704- return NULL ;
701+ goto out_unlock ;
705702
706703 init_completion (& ns -> disable_done );
707704
708705 ns -> nsid = nsid ;
709706 ns -> subsys = subsys ;
710707
708+ if (percpu_ref_init (& ns -> ref , nvmet_destroy_namespace , 0 , GFP_KERNEL ))
709+ goto out_free ;
710+
711+ if (ns -> nsid > subsys -> max_nsid )
712+ subsys -> max_nsid = nsid ;
713+
714+ if (xa_insert (& subsys -> namespaces , ns -> nsid , ns , GFP_KERNEL ))
715+ goto out_exit ;
716+
717+ subsys -> nr_namespaces ++ ;
718+
719+ mutex_unlock (& subsys -> lock );
720+
711721 down_write (& nvmet_ana_sem );
712722 ns -> anagrpid = NVMET_DEFAULT_ANA_GRPID ;
713723 nvmet_ana_group_enabled [ns -> anagrpid ]++ ;
@@ -718,6 +728,14 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)
718728 ns -> csi = NVME_CSI_NVM ;
719729
720730 return ns ;
731+ out_exit :
732+ subsys -> max_nsid = nvmet_max_nsid (subsys );
733+ percpu_ref_exit (& ns -> ref );
734+ out_free :
735+ kfree (ns );
736+ out_unlock :
737+ mutex_unlock (& subsys -> lock );
738+ return NULL ;
721739}
722740
723741static void nvmet_update_sq_head (struct nvmet_req * req )
@@ -1394,7 +1412,7 @@ static void nvmet_setup_p2p_ns_map(struct nvmet_ctrl *ctrl,
13941412
13951413 ctrl -> p2p_client = get_device (req -> p2p_client );
13961414
1397- xa_for_each (& ctrl -> subsys -> namespaces , idx , ns )
1415+ nvmet_for_each_enabled_ns (& ctrl -> subsys -> namespaces , idx , ns )
13981416 nvmet_p2pmem_ns_add_p2p (ctrl , ns );
13991417}
14001418
0 commit comments