@@ -26,6 +26,7 @@ use alloc::{
2626 sync:: { Arc , Weak } ,
2727} ;
2828use async_trait:: async_trait;
29+ use core:: any:: Any ;
2930use core:: error:: Error ;
3031use core:: marker:: PhantomData ;
3132use core:: num:: NonZeroU32 ;
@@ -157,7 +158,7 @@ impl InodeInner {
157158 InodeInner :: Regular ( File :: open_inode ( fs, inode) . unwrap ( ) )
158159 }
159160 ext4plus:: FileType :: Directory => {
160- InodeInner :: Directory ( Dir :: open_inode ( fs, inode) . await . unwrap ( ) )
161+ InodeInner :: Directory ( Dir :: open_inode ( fs, inode) . unwrap ( ) )
161162 }
162163 _ => InodeInner :: Other ( inode) ,
163164 }
@@ -378,11 +379,13 @@ where
378379 if inode. id ( ) . fs_id ( ) != fs. id ( ) {
379380 return Err ( KernelError :: Fs ( FsError :: CrossDevice ) ) ;
380381 }
381- let mut other_inode = ExtInode :: read (
382- & fs. inner ,
383- ( inode. id ( ) . inode_id ( ) as u32 ) . try_into ( ) . unwrap ( ) ,
384- )
385- . await ?;
382+ let mut other_inode = inode
383+ . as_any ( )
384+ . downcast_ref :: < Ext4Inode < CPU > > ( )
385+ . ok_or ( FsError :: CrossDevice ) ?
386+ . inner
387+ . lock ( )
388+ . await ;
386389 let file_type = other_inode. file_type ( ) ;
387390 inner_dir
388391 . link (
@@ -443,15 +446,20 @@ where
443446 return Ok ( ( ) ) ;
444447 }
445448
446- let old_parent_id = old_parent. id ( ) ;
449+ if old_parent. id ( ) . fs_id ( ) != self . id ( ) . fs_id ( ) {
450+ return Err ( KernelError :: Fs ( FsError :: CrossDevice ) ) ;
451+ }
447452 let fs = self . fs_ref . upgrade ( ) . unwrap ( ) ;
448453
449- let old_parent_inode = ExtInode :: read (
450- & fs. inner ,
451- ( old_parent_id. inode_id ( ) as u32 ) . try_into ( ) . unwrap ( ) ,
452- )
453- . await ?;
454- let old_parent_dir = Dir :: open_inode ( & fs. inner , old_parent_inode) . await ?;
454+ let old_parent_inode = old_parent
455+ . as_any ( )
456+ . downcast_ref :: < Ext4Inode < CPU > > ( )
457+ . ok_or ( FsError :: CrossDevice ) ?
458+ . inner
459+ . lock ( )
460+ . await
461+ . clone ( ) ;
462+ let old_parent_dir = Dir :: open_inode ( & fs. inner , old_parent_inode) ?;
455463
456464 let inner = self . inner . lock ( ) . await ;
457465 let inner_dir = match & * inner {
@@ -532,6 +540,13 @@ where
532540 child_inode,
533541 )
534542 . await ?;
543+ * old_parent
544+ . as_any ( )
545+ . downcast_ref :: < Ext4Inode < CPU > > ( )
546+ . ok_or ( FsError :: CrossDevice ) ?
547+ . inner
548+ . lock ( )
549+ . await = InodeInner :: Directory ( old_parent_dir) ;
535550 Ok ( ( ) )
536551 }
537552
@@ -564,6 +579,10 @@ where
564579 inner. write ( & fs. inner ) . await ?;
565580 Ok ( ( ) )
566581 }
582+
583+ fn as_any ( & self ) -> & dyn Any {
584+ self
585+ }
567586}
568587
569588/// An EXT4 filesystem instance.
0 commit comments