Add metadata in HNode
This commit is contained in:
		
							parent
							
								
									8085c2b797
								
							
						
					
					
						commit
						52b75e3e06
					
				| @ -3,7 +3,7 @@ use alloc::sync::{Arc, Weak}; | ||||
| use core::any::Any; | ||||
| use rcore_fs::vfs::*; | ||||
| use std::io::{Read, Seek, SeekFrom, Write}; | ||||
| use std::os::unix::fs::{DirEntryExt, FileTypeExt, PermissionsExt}; | ||||
| use std::os::unix::fs::{DirEntryExt, FileExt, FileTypeExt, PermissionsExt}; | ||||
| use std::path::{Path, PathBuf}; | ||||
| use std::sync::{SgxMutex as Mutex, SgxMutexGuard as MutexGuard}; | ||||
| use std::untrusted::fs; | ||||
| @ -19,6 +19,7 @@ pub struct HostFS { | ||||
| pub struct HNode { | ||||
|     path: PathBuf, | ||||
|     file: Mutex<Option<fs::File>>, | ||||
|     type_: FileType, | ||||
|     fs: Arc<HostFS>, | ||||
| } | ||||
| 
 | ||||
| @ -32,6 +33,7 @@ impl FileSystem for HostFS { | ||||
|         Arc::new(HNode { | ||||
|             path: self.path.clone(), | ||||
|             file: Mutex::new(None), | ||||
|             type_: FileType::Dir, | ||||
|             fs: self.self_ref.upgrade().unwrap(), | ||||
|         }) | ||||
|     } | ||||
| @ -76,32 +78,32 @@ macro_rules! try_std { | ||||
| 
 | ||||
| impl INode for HNode { | ||||
|     fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> { | ||||
|         if !self.path.is_file() { | ||||
|         if !self.is_file() { | ||||
|             return Err(FsError::NotFile); | ||||
|         } | ||||
|         let mut guard = self.open_file()?; | ||||
|         let file = guard.as_mut().unwrap(); | ||||
|         try_std!(file.seek(SeekFrom::Start(offset as u64))); | ||||
|         let len = try_std!(file.read(buf)); | ||||
|         let len = try_std!(file.read_at(buf, offset as u64)); | ||||
|         Ok(len) | ||||
|     } | ||||
| 
 | ||||
|     fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> { | ||||
|         if !self.path.is_file() { | ||||
|         if !self.is_file() { | ||||
|             return Err(FsError::NotFile); | ||||
|         } | ||||
|         let mut guard = self.open_file()?; | ||||
|         let file = guard.as_mut().unwrap(); | ||||
|         try_std!(file.seek(SeekFrom::Start(offset as u64))); | ||||
|         let len = try_std!(file.write(buf)); | ||||
|         let len = try_std!(file.write_at(buf, offset as u64)); | ||||
|         Ok(len) | ||||
|     } | ||||
| 
 | ||||
|     fn poll(&self) -> Result<PollStatus> { | ||||
|         let metadata = try_std!(self.path.metadata()); | ||||
|         if !metadata.is_file() { | ||||
|         if !self.is_file() { | ||||
|             return Err(FsError::NotFile); | ||||
|         } | ||||
|         let guard = self.open_file()?; | ||||
|         let file = guard.as_ref().unwrap(); | ||||
|         let metadata = try_std!(file.metadata()); | ||||
|         Ok(PollStatus { | ||||
|             read: true, | ||||
|             write: !metadata.permissions().readonly(), | ||||
| @ -110,7 +112,13 @@ impl INode for HNode { | ||||
|     } | ||||
| 
 | ||||
|     fn metadata(&self) -> Result<Metadata> { | ||||
|         let metadata = try_std!(self.path.metadata()); | ||||
|         let metadata = if self.is_file() { | ||||
|             let guard = self.open_file()?; | ||||
|             let file = guard.as_ref().unwrap(); | ||||
|             try_std!(file.metadata()) | ||||
|         } else { | ||||
|             try_std!(self.path.metadata()) | ||||
|         }; | ||||
|         Ok(metadata.into_fs_metadata()) | ||||
|     } | ||||
| 
 | ||||
| @ -125,9 +133,9 @@ impl INode for HNode { | ||||
|     } | ||||
| 
 | ||||
|     fn sync_all(&self) -> Result<()> { | ||||
|         if self.path.is_file() { | ||||
|             let mut guard = self.open_file()?; | ||||
|             let file = guard.as_mut().unwrap(); | ||||
|         if self.is_file() { | ||||
|             let guard = self.open_file()?; | ||||
|             let file = guard.as_ref().unwrap(); | ||||
|             try_std!(file.sync_all()); | ||||
|         } else { | ||||
|             warn!("no sync_all method about dir, do nothing"); | ||||
| @ -136,9 +144,9 @@ impl INode for HNode { | ||||
|     } | ||||
| 
 | ||||
|     fn sync_data(&self) -> Result<()> { | ||||
|         if self.path.is_file() { | ||||
|             let mut guard = self.open_file()?; | ||||
|             let file = guard.as_mut().unwrap(); | ||||
|         if self.is_file() { | ||||
|             let guard = self.open_file()?; | ||||
|             let file = guard.as_ref().unwrap(); | ||||
|             try_std!(file.sync_data()); | ||||
|         } else { | ||||
|             warn!("no sync_data method about dir, do nothing"); | ||||
| @ -147,11 +155,11 @@ impl INode for HNode { | ||||
|     } | ||||
| 
 | ||||
|     fn resize(&self, len: usize) -> Result<()> { | ||||
|         if !self.path.is_file() { | ||||
|         if !self.is_file() { | ||||
|             return Err(FsError::NotFile); | ||||
|         } | ||||
|         let mut guard = self.open_file()?; | ||||
|         let file = guard.as_mut().unwrap(); | ||||
|         let guard = self.open_file()?; | ||||
|         let file = guard.as_ref().unwrap(); | ||||
|         try_std!(file.set_len(len as u64)); | ||||
|         Ok(()) | ||||
|     } | ||||
| @ -162,23 +170,32 @@ impl INode for HNode { | ||||
|             return Err(FsError::EntryExist); | ||||
|         } | ||||
|         let perms = fs::Permissions::from_mode(mode as u32); | ||||
|         match type_ { | ||||
|         let file = match type_ { | ||||
|             FileType::File => { | ||||
|                 let file = try_std!(fs::File::create(&new_path)); | ||||
|                 let file = try_std!(fs::OpenOptions::new() | ||||
|                     .read(true) | ||||
|                     .write(true) | ||||
|                     .create(true) | ||||
|                     .truncate(true) | ||||
|                     .open(&new_path)); | ||||
|                 try_std!(file.set_permissions(perms)); | ||||
|                 Some(file) | ||||
|             } | ||||
|             FileType::Dir => { | ||||
|                 try_std!(fs::create_dir(&new_path)); | ||||
|                 try_std!(fs::set_permissions(&new_path, perms)); | ||||
|                 None | ||||
|             } | ||||
|             _ => { | ||||
|                 warn!("only support creating regular file or directory in HostFS"); | ||||
|                 return Err(FsError::PermError); | ||||
|             } | ||||
|         } | ||||
|         }; | ||||
| 
 | ||||
|         Ok(Arc::new(HNode { | ||||
|             path: new_path, | ||||
|             file: Mutex::new(None), | ||||
|             file: Mutex::new(file), | ||||
|             type_, | ||||
|             fs: self.fs.clone(), | ||||
|         })) | ||||
|     } | ||||
| @ -213,18 +230,27 @@ impl INode for HNode { | ||||
| 
 | ||||
|     fn find(&self, name: &str) -> Result<Arc<dyn INode>> { | ||||
|         let new_path = self.path.join(name); | ||||
|         if !new_path.exists() { | ||||
|             return Err(FsError::EntryNotFound); | ||||
|         } | ||||
|         let metadata = fs::metadata(&new_path).map_err(|_| FsError::EntryNotFound)?; | ||||
|         let file = if metadata.is_file() { | ||||
|             try_std!(fs::OpenOptions::new() | ||||
|                 .read(true) | ||||
|                 .write(true) | ||||
|                 .open(&new_path) | ||||
|                 .map(Some)) | ||||
|         } else { | ||||
|             None | ||||
|         }; | ||||
| 
 | ||||
|         Ok(Arc::new(HNode { | ||||
|             path: new_path, | ||||
|             file: Mutex::new(None), | ||||
|             file: Mutex::new(file), | ||||
|             type_: metadata.file_type().into_fs_filetype(), | ||||
|             fs: self.fs.clone(), | ||||
|         })) | ||||
|     } | ||||
| 
 | ||||
|     fn get_entry(&self, id: usize) -> Result<String> { | ||||
|         if !self.path.is_dir() { | ||||
|         if !self.is_dir() { | ||||
|             return Err(FsError::NotDir); | ||||
|         } | ||||
|         if let Some(entry) = try_std!(self.path.read_dir()).nth(id) { | ||||
| @ -238,7 +264,7 @@ impl INode for HNode { | ||||
|     } | ||||
| 
 | ||||
|     fn iterate_entries(&self, ctx: &mut DirentWriterContext) -> Result<usize> { | ||||
|         if !self.path.is_dir() { | ||||
|         if !self.is_dir() { | ||||
|             return Err(FsError::NotDir); | ||||
|         } | ||||
|         let idx = ctx.pos(); | ||||
| @ -288,20 +314,26 @@ impl HNode { | ||||
|     /// Ensure to open the file and store a `File` into `self.file`,
 | ||||
|     /// return the `MutexGuard`.
 | ||||
|     fn open_file(&self) -> Result<MutexGuard<Option<fs::File>>> { | ||||
|         if !self.path.exists() { | ||||
|             return Err(FsError::EntryNotFound); | ||||
|         } | ||||
|         let mut maybe_file = self.file.lock().unwrap(); | ||||
|         if maybe_file.is_none() { | ||||
|             let file = try_std!(fs::OpenOptions::new() | ||||
|                 .read(true) | ||||
|                 .write(true) | ||||
|                 .create(true) | ||||
|                 .open(&self.path)); | ||||
|             *maybe_file = Some(file); | ||||
|         } | ||||
|         Ok(maybe_file) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns `true` if this HNode is for a regular file.
 | ||||
|     fn is_file(&self) -> bool { | ||||
|         self.type_ == FileType::File | ||||
|     } | ||||
| 
 | ||||
|     /// Returns `true` if this HNode is for a directory.
 | ||||
|     fn is_dir(&self) -> bool { | ||||
|         self.type_ == FileType::Dir | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| trait IntoFsError { | ||||
|  | ||||
| @ -114,12 +114,21 @@ pub fn mount_nonroot_fs_according_to( | ||||
|                 mount_fs_at(sefs, root, &mc.target, follow_symlink)?; | ||||
|             } | ||||
|             TYPE_HOSTFS => { | ||||
|                 if mc.source.is_none() { | ||||
|                 let source_path = | ||||
|                     mc.source.as_ref().and_then( | ||||
|                         |source| { | ||||
|                             if source.is_dir() { | ||||
|                                 Some(source) | ||||
|                             } else { | ||||
|                                 None | ||||
|                             } | ||||
|                         }, | ||||
|                     ); | ||||
|                 if source_path.is_none() { | ||||
|                     return_errno!(EINVAL, "Source is expected for HostFS"); | ||||
|                 } | ||||
|                 let source_path = mc.source.as_ref().unwrap(); | ||||
| 
 | ||||
|                 let hostfs = HostFS::new(source_path); | ||||
|                 let hostfs = HostFS::new(source_path.unwrap()); | ||||
|                 mount_fs_at(hostfs, root, &mc.target, follow_symlink)?; | ||||
|             } | ||||
|             TYPE_RAMFS => { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user