77use deku:: { DekuContainerWrite , DekuError } ;
88use flagset:: FlagSet ;
99use hmac:: Mac ;
10+ use log:: debug;
1011use mctp:: AsyncRespChannel ;
1112use nvme:: {
1213 AdminGetLogPageLidRequestType , LidSupportedAndEffectsFlags , LogPageAttributes ,
@@ -365,6 +366,7 @@ pub enum NamespaceIdentifierType {
365366
366367#[ derive( Debug ) ]
367368pub struct Namespace {
369+ id : NamespaceId ,
368370 size : u64 ,
369371 capacity : u64 ,
370372 used : u64 ,
@@ -385,20 +387,26 @@ impl Namespace {
385387 uuid:: Builder :: from_random_bytes ( digest) . into_uuid ( )
386388 }
387389
388- pub fn new ( id : Uuid , capacity : u64 ) -> Self {
390+ pub fn new ( nsid : NamespaceId , uuid : Uuid , capacity : u64 ) -> Self {
389391 Self {
392+ id : nsid,
390393 size : capacity,
391394 capacity,
392395 used : 0 ,
393396 block_order : 9 ,
394397 nids : [
395- NamespaceIdentifierType :: Nuuid ( id ) ,
398+ NamespaceIdentifierType :: Nuuid ( uuid ) ,
396399 NamespaceIdentifierType :: Csi ( nvme:: CommandSetIdentifier :: Nvm ) ,
397400 ] ,
398401 }
399402 }
400403}
401404
405+ #[ derive( Debug , Eq , PartialEq ) ]
406+ pub enum SubsystemError {
407+ NamespaceIdentifierUnavailable ,
408+ }
409+
402410#[ derive( Clone , Copy , Debug ) ]
403411pub struct SubsystemInfo {
404412 pub pci_vid : u16 ,
@@ -480,6 +488,7 @@ pub struct Subsystem {
480488 caps : nvme:: mi:: SubsystemCapabilities ,
481489 ports : heapless:: Vec < Port , MAX_PORTS > ,
482490 ctlrs : heapless:: Vec < Controller , MAX_CONTROLLERS > ,
491+ nsids : u32 ,
483492 nss : heapless:: Vec < Namespace , MAX_NAMESPACES > ,
484493 health : SubsystemHealth ,
485494 mi : MiCapability ,
@@ -495,6 +504,7 @@ impl Subsystem {
495504 caps : nvme:: mi:: SubsystemCapabilities :: new ( ) ,
496505 ports : heapless:: Vec :: new ( ) ,
497506 ctlrs : heapless:: Vec :: new ( ) ,
507+ nsids : 0 ,
498508 nss : heapless:: Vec :: new ( ) ,
499509 health : SubsystemHealth :: new ( ) ,
500510 mi : MiCapability :: new ( ) ,
@@ -523,16 +533,33 @@ impl Subsystem {
523533 . expect ( "Invalid ControllerId provided" )
524534 }
525535
526- pub fn add_namespace ( & mut self , capacity : u64 ) -> Result < NamespaceId , u8 > {
527- debug_assert ! ( self . nss. len( ) <= u32 :: MAX . try_into( ) . unwrap( ) ) ;
528- let nsid = NamespaceId ( ( self . nss . len ( ) + 1 ) . try_into ( ) . unwrap ( ) ) ;
536+ pub fn add_namespace ( & mut self , capacity : u64 ) -> Result < NamespaceId , SubsystemError > {
537+ let Some ( allocated) = self . nsids . checked_add ( 1 ) else {
538+ debug ! ( "Implement allocation tracking with reuse" ) ;
539+ return Err ( SubsystemError :: NamespaceIdentifierUnavailable ) ;
540+ } ;
541+ self . nsids = allocated;
542+ let nsid = NamespaceId ( self . nsids ) ;
529543 let ns = Namespace :: new (
544+ nsid,
530545 Namespace :: generate_uuid ( & self . info . instance , nsid) ,
531546 capacity,
532547 ) ;
533548 match self . nss . push ( ns) {
534549 Ok ( _) => Ok ( nsid) ,
535- Err ( _) => Err ( 0x16 ) , // Namespace Identifier Unavailable
550+ Err ( _) => Err ( SubsystemError :: NamespaceIdentifierUnavailable ) ,
536551 }
537552 }
553+
554+ pub fn remove_namespace ( & mut self , nsid : NamespaceId ) -> Result < ( ) , SubsystemError > {
555+ if nsid. 0 == u32:: MAX {
556+ self . nss . clear ( ) ;
557+ return Ok ( ( ) ) ;
558+ }
559+ let Some ( e) = self . nss . iter ( ) . enumerate ( ) . find ( |args| args. 1 . id == nsid) else {
560+ return Err ( SubsystemError :: NamespaceIdentifierUnavailable ) ;
561+ } ;
562+ let _ = self . nss . swap_remove ( e. 0 ) ;
563+ Ok ( ( ) )
564+ }
538565}
0 commit comments