Skip to content

Commit

Permalink
configurable chunk size, configurable chunk type
Browse files Browse the repository at this point in the history
  • Loading branch information
wasm-forge committed Aug 29, 2024
1 parent 4c21411 commit e3e275c
Show file tree
Hide file tree
Showing 12 changed files with 638 additions and 360 deletions.
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ pub enum Error {
ExpectedToRemoveFile,
ExpectedToRemoveDirectory,
CannotRemoveOpenedNode,
CannotRemoveMountedMemoryFile,
IncompatibleChunkSize,
}
62 changes: 56 additions & 6 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,6 @@ impl FileSystem {
self.storage.get_metadata(node)
}

// find metadata for a given file descriptor.
pub fn metadata_from_node(&self, node: Node) -> Result<Metadata, Error> {
self.storage.get_metadata(node)
}

// update metadata of a given file descriptor
pub fn set_metadata(&mut self, fd: Fd, metadata: Metadata) -> Result<(), Error> {
let node = self.get_node(fd)?;
Expand Down Expand Up @@ -396,7 +391,7 @@ impl FileSystem {
}

// Opens a file and returns its new file descriptor.
pub fn open(&mut self, node: Node, stat: FdStat, flags: OpenFlags) -> Result<Fd, Error> {
fn open(&mut self, node: Node, stat: FdStat, flags: OpenFlags) -> Result<Fd, Error> {
if flags.contains(OpenFlags::EXCLUSIVE) {
return Err(Error::FileAlreadyExists);
}
Expand Down Expand Up @@ -556,6 +551,37 @@ mod tests {

use super::{Fd, FileSystem};

pub fn list_files(fs: &mut FileSystem, path: &str) -> Vec<String> {
use std::str::FromStr;

let mut res = vec![];

let dir = fs.root_fd();

let fd = fs
.open_or_create(dir, path, FdStat::default(), OpenFlags::DIRECTORY, 0)
.unwrap();

let meta = fs.metadata(fd).unwrap();

let mut entry_index = meta.first_dir_entry;

while let Some(index) = entry_index {
let entry = fs.get_direntry(fd, index).unwrap();

let filename_str: &str =
std::str::from_utf8(&entry.name.bytes[0..(entry.name.length as usize)]).unwrap();

let st = String::from_str(filename_str).unwrap();

res.push(st);

entry_index = entry.next_entry;
}

res
}

#[test]
fn get_root_info() {
let fs = test_fs();
Expand Down Expand Up @@ -1312,6 +1338,30 @@ mod tests {
println!("{:?}", buf);
}

#[test]
fn deleting_mounted_file_fails() {
let memory: VectorMemory = new_vector_memory();

let mut fs = test_fs();

let root_fd = fs.root_fd();

fs.mount_memory_file("test.txt", Box::new(memory.clone()))
.unwrap();

let res = fs.remove_file(root_fd, "test.txt");

assert!(
res.is_err(),
"Deleting a mounted file should not be allowed!"
);

// check the dir entry still exists after deletion
let files = list_files(&mut fs, "");

assert_eq!(files[0], "test.txt".to_string());
}

#[test]
fn mounted_memory_store_and_init_roundtrip() {
for mut fs in test_fs_setups("") {
Expand Down
5 changes: 2 additions & 3 deletions src/runtime/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ impl Dir {
let (node, metadata) = rm_dir_entry(self.node, path, Some(true), node_refcount, storage)?;

if metadata.link_count == 0 {
storage.rm_file(node);
storage.rm_metadata(node);
storage.rm_file(node)?;
}

Ok(())
Expand Down Expand Up @@ -103,7 +102,7 @@ impl Dir {
let (node, metadata) = rm_dir_entry(self.node, path, Some(false), node_refcount, storage)?;

if metadata.link_count == 0 {
storage.rm_file(node);
storage.rm_file(node)?;
}

Ok(())
Expand Down
8 changes: 6 additions & 2 deletions src/runtime/structure_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,11 @@ pub fn add_dir_entry(

/// Remove the directory entry from the current directory by entry name.
///
/// parent_dir_node Parent directory
/// path The name of the entry to delete
/// expect_dir If true, the directory is deleted. If false - the file is deleted. If the expected entry type does not match with the actual entry - an error is returned.
/// node_refcount A map of nodes to check if the file being deleted is opened by multiple file descriptors. Deleting an entry referenced by multiple file descriptors is not allowed and will result in an error.
/// storage The reference to the actual storage implementation
/// is_renaming true if renaming is in progress, this allows to "delete" a non-empty folder
pub fn rm_dir_entry(
parent_dir_node: Node,
path: &str,
Expand All @@ -318,6 +317,11 @@ pub fn rm_dir_entry(
let find_result = find_node_with_index(parent_dir_node, path, storage)?;

let removed_dir_entry_node = find_result.node;

if storage.is_mounted(removed_dir_entry_node) {
return Err(Error::CannotRemoveMountedMemoryFile);
}

let parent_dir_node = find_result.parent_dir;
let removed_entry_index = find_result.entry_index;
let removed_dir_entry_prev_entry = find_result.prev_entry;
Expand Down
16 changes: 16 additions & 0 deletions src/runtime/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ pub enum Whence {
END,
}

#[derive(Clone, Copy, Debug)]
pub enum ChunkSize {
CHUNK4K = 4096,
CHUNK8K = 8192,
CHUNK16K = 16384,
CHUNK32K = 32768,
CHUNK64K = 65536,
}

impl ChunkSize {
pub const VALUES: [Self; 5] = [Self::CHUNK4K, Self::CHUNK8K, Self::CHUNK16K, Self::CHUNK32K, Self::CHUNK64K];
}


bitflags! {
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct FdFlags: u16 {
Expand All @@ -48,6 +62,8 @@ bitflags! {
}
}



#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct DstBuf {
Expand Down
11 changes: 4 additions & 7 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use ic_stable_structures::Memory;

use crate::{
error::Error,
storage::types::{DirEntry, DirEntryIndex, FileChunkIndex, FileSize, Metadata, Node},
storage::types::{DirEntry, DirEntryIndex, FileSize, Metadata, Node},
};

pub mod allocator;
pub mod dummy;
pub mod stable;
pub mod transient;
Expand Down Expand Up @@ -53,10 +54,6 @@ pub trait Storage {
// Write file at the current file cursor, the cursor position will NOT be updated after reading.
fn write(&mut self, node: Node, offset: FileSize, buf: &[u8]) -> Result<FileSize, Error>;

// remove all files and
fn rm_file(&mut self, node: Node);
// Remove file chunk from a given file node.
fn rm_filechunk(&mut self, node: Node, index: FileChunkIndex);
// Remove the metadata associated with the node.
fn rm_metadata(&mut self, node: Node);
// remove all file chunks
fn rm_file(&mut self, node: Node) -> Result<(), Error>;
}
Loading

0 comments on commit e3e275c

Please sign in to comment.