Jelajahi Sumber

style: high level ops

liujingx 9 bulan lalu
induk
melakukan
9dad923969
1 mengubah file dengan 46 tambahan dan 28 penghapusan
  1. 46 28
      src/ext4/high_level.rs

+ 46 - 28
src/ext4/high_level.rs

@@ -14,16 +14,21 @@ use crate::prelude::*;
 use crate::return_error;
 
 impl Ext4 {
-    /// Look up an object in the filesystem.
+    /// Look up an object in the filesystem recursively.
     ///
-    /// ## Params
+    /// # Params
     ///
     /// * `root` - The inode id of the root directory for search.
-    /// * `path` - The path of the object to be opened.
+    /// * `path` - The relative path of the object to be opened.
     ///
-    /// ## Return
+    /// # Return
     ///
     /// `Ok(inode)` - Inode id of the object
+    ///
+    /// # Error
+    ///
+    /// * `ENOTDIR` - Any parent along `path` is not a directory.
+    /// * `ENOENT` - The object does not exist.
     pub fn generic_lookup(&self, root: InodeId, path: &str) -> Result<InodeId> {
         trace!("generic_lookup({}, {})", root, path);
         // Search from the given parent inode
@@ -36,18 +41,24 @@ impl Ext4 {
         Ok(cur)
     }
 
-    /// Open a file in the filesystem. Return error if the file does not exist.
+    /// (DEPRECATED) Open a file in the filesystem.
     ///
-    /// ## Params
+    /// # Params
     ///
     /// * `root` - The inode id of the root directory for search.
     /// * `path` - The path of the object to be opened.
     /// * `flags` - The open flags. Creation (O_CREAT, O_EXCL, O_NOCTTY) flags
     ///             will be ignored.
     ///
-    /// ## Return
+    /// # Return
     ///
     /// `Ok(fh)` - File handler
+    /// 
+    /// # Error
+    /// 
+    /// * `ENOENT` - The file does not exist.
+    /// * `EISDIR` - The file is a directory.
+    #[deprecated]
     pub fn generic_open(&self, root: InodeId, path: &str, flags: OpenFlags) -> Result<FileHandler> {
         let inode_id = self.generic_lookup(root, path)?;
         let inode = self.read_inode(inode_id);
@@ -58,45 +69,51 @@ impl Ext4 {
         Ok(FileHandler::new(inode.id, flags, inode.inode.size()))
     }
 
-    /// Create an object in the filesystem. Return error if the object already exists.
+    /// Create an object in the filesystem.
     ///
     /// This function will perform recursive-creation i.e. if the parent
     /// directory does not exist, it will be created as well.
     ///
-    /// ## Params
+    /// # Params
     ///
     /// * `root` - The inode id of the starting directory for search.
-    /// * `path` - The path of the object to create.
+    /// * `path` - The relative path of the object to create.
     /// * `mode` - file mode and type to create
     ///
-    /// ## Return
+    /// # Return
     ///
     /// `Ok(inode)` - Inode id of the created object
+    ///
+    /// # Error
+    ///
+    /// * `ENOTDIR` - Any parent along `path` is not a directory.
+    /// * `EEXIST` - The object already exists.
     pub fn generic_create(&self, root: InodeId, path: &str, mode: InodeMode) -> Result<InodeId> {
         // Search from the given parent inode
         let mut cur = self.read_inode(root);
         let search_path = Self::split_path(path);
-
         // Search recursively
         for (i, path) in search_path.iter().enumerate() {
             if !cur.inode.is_dir() {
                 return_error!(ErrCode::ENOTDIR, "Parent {} is not a directory", cur.id);
             }
             match self.dir_find_entry(&cur, &path) {
-                Ok(de) => {
-                    // If the object exists, check the type
-                    cur = self.read_inode(de);
+                Ok(id) => {
+                    if i == search_path.len() - 1 {
+                        // Reach the object and it already exists
+                        return_error!(ErrCode::EEXIST, "Object {}/{} already exists", root, path);
+                    }
+                    cur = self.read_inode(id);
                 }
                 Err(e) => {
                     if e.code() != ErrCode::ENOENT {
-                        return Err(e);
+                        return_error!(e.code(), "Unexpected error: {:?}", e);
                     }
-                    // If the object does not exist, create it
                     let mut child = if i == search_path.len() - 1 {
-                        // Create the file
+                        // Reach the object, create it
                         self.create_inode(mode)?
                     } else {
-                        // Create the directory
+                        // Create parent directory
                         self.create_inode(InodeMode::DIRECTORY | InodeMode::ALL_RWX)?
                     };
                     self.link_inode(&mut cur, &mut child, path)?;
@@ -104,17 +121,20 @@ impl Ext4 {
                 }
             }
         }
-
         Ok(cur.id)
     }
 
-    /// Remove an object from the filesystem. Return error if the object is a
-    /// directory and is not empty.
+    /// Remove an object from the filesystem.
     ///
-    /// ## Params
+    /// # Params
     ///
     /// * `root` - The inode id of the starting directory for search.
     /// * `path` - The path of the object to remove.
+    ///
+    /// # Error
+    ///
+    /// * `ENOENT` - The object does not exist.
+    /// * `ENOTEMPTY` - The object is a non-empty directory.
     pub fn generic_remove(&self, root: InodeId, path: &str) -> Result<()> {
         // Get the parent directory path and the file name
         let mut search_path = Self::split_path(path);
@@ -126,11 +146,9 @@ impl Ext4 {
         let child_id = self.generic_lookup(parent_id, &file_name)?;
         let mut parent = self.read_inode(parent_id);
         let mut child = self.read_inode(child_id);
-        if child.inode.is_dir() {
-            // Check if the directory is empty
-            if self.dir_list_entries(&child).len() > 2 {
-                return_error!(ErrCode::ENOTEMPTY, "Directory {} not empty", path);
-            }
+        // Check if child is a non-empty directory
+        if child.inode.is_dir() && self.dir_list_entries(&child).len() > 2 {
+            return_error!(ErrCode::ENOTEMPTY, "Directory {} not empty", path);
         }
         // Unlink the file
         self.unlink_inode(&mut parent, &mut child, file_name, true)