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