Skip to main content

FilesystemCore

Struct FilesystemCore 

Source
pub struct FilesystemCore { /* private fields */ }
Expand description

The main filesystem core. Owns the block store, crypto, codec, allocator, and transaction manager. Provides high-level filesystem operations.

Implementations§

Source§

impl FilesystemCore

Source

pub fn new(store: Arc<dyn BlockStore>, crypto: Arc<dyn CryptoEngine>) -> Self

Create a new FilesystemCore backed by the given store and crypto engine.

Examples found in repository?
examples/create_image.rs (line 33)
15fn main() {
16    let path = std::env::current_dir()
17        .unwrap()
18        .join("sample.dcfs")
19        .to_string_lossy()
20        .to_string();
21
22    // Remove leftover from a previous run, if any.
23    let _ = std::fs::remove_file(&path);
24
25    // 64 blocks × 64 KiB = 4 MiB image.
26    let total_blocks: u64 = 64;
27    let store = Arc::new(
28        DiskBlockStore::create(&path, DEFAULT_BLOCK_SIZE, total_blocks)
29            .expect("failed to create image file"),
30    );
31
32    let crypto = Arc::new(ChaChaEngine::generate().expect("failed to init crypto"));
33    let mut fs = FilesystemCore::new(store, crypto);
34
35    fs.init_filesystem().expect("init_filesystem failed");
36
37    // Create a text file.
38    fs.create_file("hello.txt").expect("create_file failed");
39    fs.write_file("hello.txt", 0, b"Hello, hex editor!")
40        .expect("write_file failed");
41
42    // Create a directory.
43    fs.create_directory("notes")
44        .expect("create_directory failed");
45
46    // Create a larger binary file so there's more to look at.
47    let pattern: Vec<u8> = (0..=255).cycle().take(200_000).collect();
48    fs.create_file("pattern.bin").expect("create_file failed");
49    fs.write_file("pattern.bin", 0, &pattern)
50        .expect("write_file failed");
51
52    fs.sync().expect("sync failed");
53
54    println!("Filesystem image written to:\n  {path}");
55    println!(
56        "  {} blocks × {} bytes = {} bytes total",
57        total_blocks,
58        DEFAULT_BLOCK_SIZE,
59        total_blocks as usize * DEFAULT_BLOCK_SIZE
60    );
61}
More examples
Hide additional examples
examples/network_mount.rs (line 101)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn init_filesystem(&mut self) -> FsResult<()>

Initialize a brand-new filesystem on the block store. Writes the storage header, creates the root directory, and commits.

Examples found in repository?
examples/create_image.rs (line 35)
15fn main() {
16    let path = std::env::current_dir()
17        .unwrap()
18        .join("sample.dcfs")
19        .to_string_lossy()
20        .to_string();
21
22    // Remove leftover from a previous run, if any.
23    let _ = std::fs::remove_file(&path);
24
25    // 64 blocks × 64 KiB = 4 MiB image.
26    let total_blocks: u64 = 64;
27    let store = Arc::new(
28        DiskBlockStore::create(&path, DEFAULT_BLOCK_SIZE, total_blocks)
29            .expect("failed to create image file"),
30    );
31
32    let crypto = Arc::new(ChaChaEngine::generate().expect("failed to init crypto"));
33    let mut fs = FilesystemCore::new(store, crypto);
34
35    fs.init_filesystem().expect("init_filesystem failed");
36
37    // Create a text file.
38    fs.create_file("hello.txt").expect("create_file failed");
39    fs.write_file("hello.txt", 0, b"Hello, hex editor!")
40        .expect("write_file failed");
41
42    // Create a directory.
43    fs.create_directory("notes")
44        .expect("create_directory failed");
45
46    // Create a larger binary file so there's more to look at.
47    let pattern: Vec<u8> = (0..=255).cycle().take(200_000).collect();
48    fs.create_file("pattern.bin").expect("create_file failed");
49    fs.write_file("pattern.bin", 0, &pattern)
50        .expect("write_file failed");
51
52    fs.sync().expect("sync failed");
53
54    println!("Filesystem image written to:\n  {path}");
55    println!(
56        "  {} blocks × {} bytes = {} bytes total",
57        total_blocks,
58        DEFAULT_BLOCK_SIZE,
59        total_blocks as usize * DEFAULT_BLOCK_SIZE
60    );
61}
More examples
Hide additional examples
examples/network_mount.rs (line 106)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn open(&mut self) -> FsResult<()>

Open / mount an existing filesystem by recovering the latest root pointer.

Examples found in repository?
examples/network_mount.rs (line 109)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn create_file(&mut self, name: &str) -> FsResult<()>

Create a new empty file in the given directory (by inode ref). For V1, only root directory is supported.

Examples found in repository?
examples/create_image.rs (line 38)
15fn main() {
16    let path = std::env::current_dir()
17        .unwrap()
18        .join("sample.dcfs")
19        .to_string_lossy()
20        .to_string();
21
22    // Remove leftover from a previous run, if any.
23    let _ = std::fs::remove_file(&path);
24
25    // 64 blocks × 64 KiB = 4 MiB image.
26    let total_blocks: u64 = 64;
27    let store = Arc::new(
28        DiskBlockStore::create(&path, DEFAULT_BLOCK_SIZE, total_blocks)
29            .expect("failed to create image file"),
30    );
31
32    let crypto = Arc::new(ChaChaEngine::generate().expect("failed to init crypto"));
33    let mut fs = FilesystemCore::new(store, crypto);
34
35    fs.init_filesystem().expect("init_filesystem failed");
36
37    // Create a text file.
38    fs.create_file("hello.txt").expect("create_file failed");
39    fs.write_file("hello.txt", 0, b"Hello, hex editor!")
40        .expect("write_file failed");
41
42    // Create a directory.
43    fs.create_directory("notes")
44        .expect("create_directory failed");
45
46    // Create a larger binary file so there's more to look at.
47    let pattern: Vec<u8> = (0..=255).cycle().take(200_000).collect();
48    fs.create_file("pattern.bin").expect("create_file failed");
49    fs.write_file("pattern.bin", 0, &pattern)
50        .expect("write_file failed");
51
52    fs.sync().expect("sync failed");
53
54    println!("Filesystem image written to:\n  {path}");
55    println!(
56        "  {} blocks × {} bytes = {} bytes total",
57        total_blocks,
58        DEFAULT_BLOCK_SIZE,
59        total_blocks as usize * DEFAULT_BLOCK_SIZE
60    );
61}
More examples
Hide additional examples
examples/network_mount.rs (line 114)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn write_file( &mut self, name: &str, offset: u64, data: &[u8], ) -> FsResult<()>

Write data to a file. For V1, this replaces the entire file content (single chunk only if it fits in one block).

Examples found in repository?
examples/create_image.rs (line 39)
15fn main() {
16    let path = std::env::current_dir()
17        .unwrap()
18        .join("sample.dcfs")
19        .to_string_lossy()
20        .to_string();
21
22    // Remove leftover from a previous run, if any.
23    let _ = std::fs::remove_file(&path);
24
25    // 64 blocks × 64 KiB = 4 MiB image.
26    let total_blocks: u64 = 64;
27    let store = Arc::new(
28        DiskBlockStore::create(&path, DEFAULT_BLOCK_SIZE, total_blocks)
29            .expect("failed to create image file"),
30    );
31
32    let crypto = Arc::new(ChaChaEngine::generate().expect("failed to init crypto"));
33    let mut fs = FilesystemCore::new(store, crypto);
34
35    fs.init_filesystem().expect("init_filesystem failed");
36
37    // Create a text file.
38    fs.create_file("hello.txt").expect("create_file failed");
39    fs.write_file("hello.txt", 0, b"Hello, hex editor!")
40        .expect("write_file failed");
41
42    // Create a directory.
43    fs.create_directory("notes")
44        .expect("create_directory failed");
45
46    // Create a larger binary file so there's more to look at.
47    let pattern: Vec<u8> = (0..=255).cycle().take(200_000).collect();
48    fs.create_file("pattern.bin").expect("create_file failed");
49    fs.write_file("pattern.bin", 0, &pattern)
50        .expect("write_file failed");
51
52    fs.sync().expect("sync failed");
53
54    println!("Filesystem image written to:\n  {path}");
55    println!(
56        "  {} blocks × {} bytes = {} bytes total",
57        total_blocks,
58        DEFAULT_BLOCK_SIZE,
59        total_blocks as usize * DEFAULT_BLOCK_SIZE
60    );
61}
More examples
Hide additional examples
examples/network_mount.rs (line 119)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn read_file( &self, name: &str, offset: u64, len: usize, ) -> FsResult<Vec<u8>>

Read file data. Returns the requested slice of the file.

Examples found in repository?
examples/network_mount.rs (line 122)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn list_directory(&self) -> FsResult<Vec<DirListEntry>>

List entries in the root directory.

Examples found in repository?
examples/network_mount.rs (line 126)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}
Source

pub fn create_directory(&mut self, name: &str) -> FsResult<()>

Create a subdirectory in the root directory.

Examples found in repository?
examples/create_image.rs (line 43)
15fn main() {
16    let path = std::env::current_dir()
17        .unwrap()
18        .join("sample.dcfs")
19        .to_string_lossy()
20        .to_string();
21
22    // Remove leftover from a previous run, if any.
23    let _ = std::fs::remove_file(&path);
24
25    // 64 blocks × 64 KiB = 4 MiB image.
26    let total_blocks: u64 = 64;
27    let store = Arc::new(
28        DiskBlockStore::create(&path, DEFAULT_BLOCK_SIZE, total_blocks)
29            .expect("failed to create image file"),
30    );
31
32    let crypto = Arc::new(ChaChaEngine::generate().expect("failed to init crypto"));
33    let mut fs = FilesystemCore::new(store, crypto);
34
35    fs.init_filesystem().expect("init_filesystem failed");
36
37    // Create a text file.
38    fs.create_file("hello.txt").expect("create_file failed");
39    fs.write_file("hello.txt", 0, b"Hello, hex editor!")
40        .expect("write_file failed");
41
42    // Create a directory.
43    fs.create_directory("notes")
44        .expect("create_directory failed");
45
46    // Create a larger binary file so there's more to look at.
47    let pattern: Vec<u8> = (0..=255).cycle().take(200_000).collect();
48    fs.create_file("pattern.bin").expect("create_file failed");
49    fs.write_file("pattern.bin", 0, &pattern)
50        .expect("write_file failed");
51
52    fs.sync().expect("sync failed");
53
54    println!("Filesystem image written to:\n  {path}");
55    println!(
56        "  {} blocks × {} bytes = {} bytes total",
57        total_blocks,
58        DEFAULT_BLOCK_SIZE,
59        total_blocks as usize * DEFAULT_BLOCK_SIZE
60    );
61}
Source

pub fn remove_file(&mut self, name: &str) -> FsResult<()>

Remove a file from the root directory.

Source

pub fn rename(&mut self, old_name: &str, new_name: &str) -> FsResult<()>

Rename a file or directory within the root directory.

Source

pub fn sync(&self) -> FsResult<()>

Sync / flush. Calls through to the block store sync.

Examples found in repository?
examples/create_image.rs (line 52)
15fn main() {
16    let path = std::env::current_dir()
17        .unwrap()
18        .join("sample.dcfs")
19        .to_string_lossy()
20        .to_string();
21
22    // Remove leftover from a previous run, if any.
23    let _ = std::fs::remove_file(&path);
24
25    // 64 blocks × 64 KiB = 4 MiB image.
26    let total_blocks: u64 = 64;
27    let store = Arc::new(
28        DiskBlockStore::create(&path, DEFAULT_BLOCK_SIZE, total_blocks)
29            .expect("failed to create image file"),
30    );
31
32    let crypto = Arc::new(ChaChaEngine::generate().expect("failed to init crypto"));
33    let mut fs = FilesystemCore::new(store, crypto);
34
35    fs.init_filesystem().expect("init_filesystem failed");
36
37    // Create a text file.
38    fs.create_file("hello.txt").expect("create_file failed");
39    fs.write_file("hello.txt", 0, b"Hello, hex editor!")
40        .expect("write_file failed");
41
42    // Create a directory.
43    fs.create_directory("notes")
44        .expect("create_directory failed");
45
46    // Create a larger binary file so there's more to look at.
47    let pattern: Vec<u8> = (0..=255).cycle().take(200_000).collect();
48    fs.create_file("pattern.bin").expect("create_file failed");
49    fs.write_file("pattern.bin", 0, &pattern)
50        .expect("write_file failed");
51
52    fs.sync().expect("sync failed");
53
54    println!("Filesystem image written to:\n  {path}");
55    println!(
56        "  {} blocks × {} bytes = {} bytes total",
57        total_blocks,
58        DEFAULT_BLOCK_SIZE,
59        total_blocks as usize * DEFAULT_BLOCK_SIZE
60    );
61}
More examples
Hide additional examples
examples/network_mount.rs (line 134)
22fn main() {
23    let args: Vec<String> = std::env::args().collect();
24
25    let mut addr = "127.0.0.1:9100";
26    let mut server_name = "localhost";
27    let mut cert = "certs/client.pem";
28    let mut key = "certs/client-key.pem";
29    let mut ca = "certs/ca.pem";
30    let mut master_key_hex = "";
31    let mut init = false;
32
33    let mut i = 1;
34    while i < args.len() {
35        match args[i].as_str() {
36            "--addr" => {
37                addr = &args[i + 1];
38                i += 2;
39            }
40            "--server-name" => {
41                server_name = &args[i + 1];
42                i += 2;
43            }
44            "--cert" => {
45                cert = &args[i + 1];
46                i += 2;
47            }
48            "--key" => {
49                key = &args[i + 1];
50                i += 2;
51            }
52            "--ca" => {
53                ca = &args[i + 1];
54                i += 2;
55            }
56            "--master-key" => {
57                master_key_hex = &args[i + 1];
58                i += 2;
59            }
60            "--init" => {
61                init = true;
62                i += 1;
63            }
64            other => {
65                eprintln!("unknown argument: {other}");
66                std::process::exit(1);
67            }
68        }
69    }
70
71    if master_key_hex.is_empty() || master_key_hex.len() != 64 {
72        eprintln!("--master-key must be a 64-character hex string (32 bytes)");
73        std::process::exit(1);
74    }
75
76    let master_key: Vec<u8> = (0..32)
77        .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
78        .collect();
79
80    // ── Connect ─────────────────────────────────────────────
81    println!("Connecting to {addr} (SNI: {server_name})...");
82    let net = NetworkBlockStore::connect(
83        addr,
84        server_name,
85        Path::new(cert),
86        Path::new(key),
87        Path::new(ca),
88    )
89    .expect("failed to connect to server");
90
91    println!(
92        "Connected: {} blocks × {} bytes ({} MiB)",
93        net.total_blocks(),
94        net.block_size(),
95        net.total_blocks() as usize * net.block_size() / (1024 * 1024)
96    );
97
98    // ── Wrap with cache ─────────────────────────────────────
99    let store = Arc::new(CachedBlockStore::new(net, 1024));
100    let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
101    let mut fs = FilesystemCore::new(store.clone(), crypto);
102
103    // ── Mount or init ───────────────────────────────────────
104    if init {
105        println!("Initializing new filesystem...");
106        fs.init_filesystem().expect("init_filesystem failed");
107    } else {
108        println!("Mounting existing filesystem...");
109        fs.open().expect("open failed");
110    }
111
112    // ── Demo operations ─────────────────────────────────────
113    println!("\nCreating file 'hello.txt'...");
114    match fs.create_file("hello.txt") {
115        Ok(()) => {}
116        Err(e) => println!("  (skipped: {e})"),
117    }
118
119    fs.write_file("hello.txt", 0, b"Hello from the network!")
120        .expect("write failed");
121
122    let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
123    println!("Read back: {:?}", String::from_utf8_lossy(&data));
124
125    println!("\nListing root directory:");
126    for entry in fs.list_directory().expect("list failed") {
127        println!(
128            "  {:?}  {:>10} bytes  {}",
129            entry.kind, entry.size, entry.name
130        );
131    }
132
133    // ── Sync ────────────────────────────────────────────────
134    fs.sync().expect("sync failed");
135    println!("\nAll data synced to server.");
136}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V