2016-09-20 16:47:16 +02:00
use alloc ::arc ::Arc ;
use alloc ::boxed ::Box ;
use collections ::BTreeMap ;
use core ::sync ::atomic ::{ AtomicUsize , Ordering } ;
use spin ::RwLock ;
2016-09-20 22:50:04 +02:00
use context ;
2016-09-21 00:23:28 +02:00
use syscall ::error ::* ;
use syscall ::scheme ::Scheme ;
use scheme ;
2016-09-20 16:47:16 +02:00
use scheme ::user ::{ UserInner , UserScheme } ;
pub struct RootScheme {
next_id : AtomicUsize ,
handles : RwLock < BTreeMap < usize , Arc < UserInner > > >
}
impl RootScheme {
pub fn new ( ) -> RootScheme {
RootScheme {
next_id : AtomicUsize ::new ( 0 ) ,
handles : RwLock ::new ( BTreeMap ::new ( ) )
}
}
}
impl Scheme for RootScheme {
2016-10-06 02:01:05 +02:00
fn open ( & self , path : & [ u8 ] , _flags : usize , _uid : u32 , _gid : u32 ) -> Result < usize > {
2016-09-20 22:50:04 +02:00
let context = {
let contexts = context ::contexts ( ) ;
2016-09-21 00:23:28 +02:00
let context = contexts . current ( ) . ok_or ( Error ::new ( ESRCH ) ) ? ;
2016-09-20 22:50:04 +02:00
Arc ::downgrade ( & context )
} ;
2016-09-20 16:47:16 +02:00
let inner = {
let mut schemes = scheme ::schemes_mut ( ) ;
if schemes . get_name ( path ) . is_some ( ) {
2016-09-21 00:23:28 +02:00
return Err ( Error ::new ( EEXIST ) ) ;
2016-09-20 16:47:16 +02:00
}
2016-09-20 22:50:04 +02:00
let inner = Arc ::new ( UserInner ::new ( context ) ) ;
2016-09-24 01:54:39 +02:00
let id = schemes . insert ( path . to_vec ( ) . into_boxed_slice ( ) , Arc ::new ( Box ::new ( UserScheme ::new ( Arc ::downgrade ( & inner ) ) ) ) ) . expect ( " failed to insert user scheme " ) ;
inner . scheme_id . store ( id , Ordering ::SeqCst ) ;
2016-09-20 16:47:16 +02:00
inner
} ;
let id = self . next_id . fetch_add ( 1 , Ordering ::SeqCst ) ;
self . handles . write ( ) . insert ( id , inner ) ;
Ok ( id )
}
fn dup ( & self , file : usize ) -> Result < usize > {
2016-09-20 17:21:54 +02:00
let mut handles = self . handles . write ( ) ;
2016-09-20 16:47:16 +02:00
let inner = {
2016-09-21 00:23:28 +02:00
let inner = handles . get ( & file ) . ok_or ( Error ::new ( EBADF ) ) ? ;
2016-09-20 16:47:16 +02:00
inner . clone ( )
} ;
let id = self . next_id . fetch_add ( 1 , Ordering ::SeqCst ) ;
2016-09-20 17:21:54 +02:00
handles . insert ( id , inner ) ;
2016-09-20 16:47:16 +02:00
Ok ( id )
}
fn read ( & self , file : usize , buf : & mut [ u8 ] ) -> Result < usize > {
let inner = {
let handles = self . handles . read ( ) ;
2016-09-21 00:23:28 +02:00
let inner = handles . get ( & file ) . ok_or ( Error ::new ( EBADF ) ) ? ;
2016-09-20 16:47:16 +02:00
inner . clone ( )
} ;
inner . read ( buf )
}
fn write ( & self , file : usize , buf : & [ u8 ] ) -> Result < usize > {
let inner = {
let handles = self . handles . read ( ) ;
2016-09-21 00:23:28 +02:00
let inner = handles . get ( & file ) . ok_or ( Error ::new ( EBADF ) ) ? ;
2016-09-20 16:47:16 +02:00
inner . clone ( )
} ;
inner . write ( buf )
}
2016-09-21 00:23:28 +02:00
fn fsync ( & self , _file : usize ) -> Result < usize > {
Ok ( 0 )
2016-09-20 16:47:16 +02:00
}
2016-09-21 00:23:28 +02:00
fn close ( & self , file : usize ) -> Result < usize > {
self . handles . write ( ) . remove ( & file ) . ok_or ( Error ::new ( EBADF ) ) . and ( Ok ( 0 ) )
2016-09-20 16:47:16 +02:00
}
}