Skip to content

Commit

Permalink
refactor metadata functions into metadata provider
Browse files Browse the repository at this point in the history
  • Loading branch information
wasm-forge committed Dec 28, 2024
1 parent 2682773 commit 4a9debd
Show file tree
Hide file tree
Showing 15 changed files with 785 additions and 659 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stable-fs"
version = "0.6.5"
version = "0.7.0"
edition = "2021"
description = "A Simple File system implementing WASI endpoints and using the stable structures of the Internet Computer"
keywords = ["ic", "internet-computer", "file-system"]
Expand All @@ -13,8 +13,8 @@ ic-cdk = "0.17.1"

ic-stable-structures = "0.6.7"

serde = "1.0.216"
serde_bytes = "0.11"
serde = "1.0.217"
serde_bytes = "0.11.15"
ciborium = "0.2.2"

[dev-dependencies]
Expand Down
5 changes: 4 additions & 1 deletion src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ impl FileSystem {
Ok(())
}

// Get the metadata for a given file descriptor
// Get the metadata for a given node
pub fn metadata_from_node(&self, node: Node) -> Result<Metadata, Error> {
self.storage.get_metadata(node)
}
Expand Down Expand Up @@ -416,7 +416,9 @@ impl FileSystem {
if flags.contains(OpenFlags::EXCLUSIVE) {
return Err(Error::FileAlreadyExists);
}

let metadata = self.storage.get_metadata(node)?;

match metadata.file_type {
FileType::Directory => {
let dir = Dir::new(node, stat, self.storage.as_mut())?;
Expand Down Expand Up @@ -446,6 +448,7 @@ impl FileSystem {
stat: FdStat,
ctime: u64,
) -> Result<Fd, Error> {

let dir = self.get_dir(parent)?;

let child = dir.create_file(
Expand Down
62 changes: 62 additions & 0 deletions src/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,54 @@ mod fns {
panic!("unintended call failure!");
}
}

pub(crate) fn check_metadata_format(pic: &PocketIc) {
pic.query_call(
active_canister(),
Principal::anonymous(),
"check_metadata_format",
encode_one(()).unwrap(),
)
.unwrap();
}

pub(crate) fn check_metadata_deserialization_into_repr_c(pic: &PocketIc) -> u64 {
let response = pic
.query_call(
active_canister(),
Principal::anonymous(),
"check_metadata_deserialization_into_repr_c",
encode_one(()).unwrap(),
)
.unwrap();

if let WasmResult::Reply(response) = response {
let result: u64 = decode_one(&response).unwrap();

result
} else {
panic!("unintended call failure!");
}
}

pub(crate) fn check_metadata_binary(pic: &PocketIc) -> String {
let response = pic
.query_call(
active_canister(),
Principal::anonymous(),
"check_metadata_binary",
encode_one(()).unwrap(),
)
.unwrap();

if let WasmResult::Reply(response) = response {
let result: String = decode_one(&response).unwrap();

result
} else {
panic!("unintended call failure!");
}
}
}

#[test]
Expand Down Expand Up @@ -538,3 +586,17 @@ fn large_file_second_write() {

assert_eq!(size, 100_000_000);
}


#[test]
fn check_metadata_binary() {
let pic = setup_initial_canister();

// we should track any changes that affect Metadata binary representation in memory
// as it is stored directly without explicit serialization for the sake of performance.
let bin = fns::check_metadata_binary(&pic);

assert_eq!(&bin,
"0300000000000000040000000000000006000000000000000800000000000000410000000000000042000000000000004300000000000000010000000c000000010000000d00000002ffffff00000000");

}
2 changes: 1 addition & 1 deletion src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod allocator;
mod chunk_iterator;
pub mod dummy;
mod journal;
mod metadata_cache;
mod metadata_provider;
mod ptr_cache;
pub mod stable;
pub mod transient;
Expand Down
1 change: 1 addition & 0 deletions src/storage/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct ChunkPtrAllocator<M: Memory> {

impl<M: Memory> ChunkPtrAllocator<M> {
pub fn new(v2_available_chunks: VirtualMemory<M>) -> Result<ChunkPtrAllocator<M>, Error> {

// init avaiable chunks
if v2_available_chunks.size() == 0 {
v2_available_chunks.grow(1);
Expand Down
155 changes: 4 additions & 151 deletions src/storage/journal.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
use ic_stable_structures::{memory_manager::VirtualMemory, Memory};

use crate::{
error::Error,
runtime::structure_helpers::{read_obj, write_obj},
};

use super::types::{Metadata, Node};

// index containing cached metadata
const MOUNTED_META_PTR: u64 = 16;
use crate::error::Error;

pub struct CacheJournal<M: Memory> {
journal: VirtualMemory<M>,

mounted_node: Node,
mounted_meta: Metadata,
}

// The cache stored in stable memory for some information that has to be stored between upgrades.
Expand All @@ -27,14 +16,7 @@ impl<M: Memory> CacheJournal<M> {
let b = [b'F', b'S', b'J', b'1', 0, 0, 0, 0];
journal.write(0, &b);

let mut cache_journal = CacheJournal {
journal,
mounted_node: u64::MAX,
mounted_meta: Metadata::default(),
};

// reset mounted meta node
cache_journal.reset_mounted_meta();
let cache_journal = CacheJournal { journal };

cache_journal
} else {
Expand All @@ -47,60 +29,16 @@ impl<M: Memory> CacheJournal<M> {
return Err(Error::InvalidMagicMarker);
}

let mut cache_journal = CacheJournal {
journal,
mounted_node: u64::MAX,
mounted_meta: Metadata::default(),
};
let cache_journal = CacheJournal { journal };

// init local cache variables
read_obj(
&cache_journal.journal,
MOUNTED_META_PTR,
&mut cache_journal.mounted_node,
);
read_obj(
&cache_journal.journal,
MOUNTED_META_PTR + 8,
&mut cache_journal.mounted_meta,
);
//...

cache_journal
};

Ok(cache_journal)
}

pub fn read_mounted_meta_node(&self) -> Option<Node> {
let ret = self.mounted_node;

//read_obj(&self.journal, MOUNTED_META_PTR, &mut ret);
if ret == u64::MAX {
return None;
}

Some(ret)
}

pub fn read_mounted_meta(&self, meta: &mut Metadata) {
*meta = self.mounted_meta.clone();

//read_obj(&self.journal, MOUNTED_META_PTR + 8, meta);
}

pub fn reset_mounted_meta(&mut self) {
self.mounted_node = u64::MAX;
self.mounted_meta = Metadata::default();

write_obj(&self.journal, MOUNTED_META_PTR, &(u64::MAX as Node));
}

pub fn write_mounted_meta(&mut self, node: &Node, meta: &Metadata) {
self.mounted_node = *node;
self.mounted_meta = (*meta).clone();

write_obj(&self.journal, MOUNTED_META_PTR, &(*node, (*meta).clone()));
}
}

#[cfg(test)]
Expand All @@ -113,45 +51,6 @@ mod tests {

use super::*;

#[test]
fn cache_journal_metadata_roundtrip() {
let mem = new_vector_memory();
let memory_manager = MemoryManager::init(mem);
let journal_memory = memory_manager.get(MemoryId::new(1));
let mut journal = CacheJournal::new(journal_memory).unwrap();

let node: Node = 123;
let meta = Metadata {
node: 123,
file_type: crate::storage::types::FileType::RegularFile,
link_count: 1,
size: 1234,
times: crate::storage::types::Times {
accessed: 48,
modified: 388,
created: 34,
},
first_dir_entry: None,
last_dir_entry: Some(876),
chunk_type: None,
};

let mut node2 = 0;
let mut meta2 = Metadata::default();

assert_ne!(node, node2);
assert_ne!(meta, meta2);

journal.write_mounted_meta(&node, &meta);

node2 = journal.read_mounted_meta_node().unwrap();

journal.read_mounted_meta(&mut meta2);

assert_eq!(node, node2);
assert_eq!(meta, meta2);
}

#[test]
fn fsj1_marker_is_written() {
let mem = new_vector_memory();
Expand Down Expand Up @@ -194,50 +93,4 @@ mod tests {

assert!(res.is_err());
}

#[test]
fn initial_node_value() {
let mem = new_vector_memory();
let memory_manager = MemoryManager::init(mem);
let journal_memory = memory_manager.get(MemoryId::new(1));
let journal = CacheJournal::new(journal_memory).unwrap();

assert_eq!(journal.read_mounted_meta_node(), None);
}

#[test]
fn updated_node_value_after_upgrade() {
let mem = new_vector_memory();
let memory_manager = MemoryManager::init(mem);
let journal_memory = memory_manager.get(MemoryId::new(1));
let mut journal = CacheJournal::new(journal_memory).unwrap();

assert_eq!(journal.read_mounted_meta_node(), None);

let meta = Metadata {
node: 123,
file_type: crate::storage::types::FileType::RegularFile,
link_count: 1,
size: 1234,
times: crate::storage::types::Times {
accessed: 48,
modified: 388,
created: 34,
},
first_dir_entry: None,
last_dir_entry: Some(876),
chunk_type: None,
};

journal.write_mounted_meta(&123, &meta);

let journal = CacheJournal::new(memory_manager.get(MemoryId::new(1))).unwrap();

assert_eq!(journal.read_mounted_meta_node(), Some(123));

let mut meta2 = Metadata::default();
journal.read_mounted_meta(&mut meta2);

assert_eq!(meta, meta2);
}
}
Loading

0 comments on commit 4a9debd

Please sign in to comment.