book/src/development/design/filesystem.md

89 lines
4.1 KiB
Markdown
Raw Normal View History

2023-04-17 21:23:10 +00:00
# Filesystem
2023-04-17 23:51:01 +00:00
```admonish warning
I have *no* idea what I'm doing here. If you do, *please* let me know, and fix this!
This is just some light brainstorming of how I think this might work.
```
## Prelude
Right now, [actors](/development/design/actor.md) are stored in **RAM** only.
But, what if we want them to be persistent on system reboot? They need to be saved to the disk.
I don't want to provide a simple filesystem interface to programs like **UNIX** does however.
Instead, all data should be just stored in *actors*, then the actors will decide whether or not they should be saved.
They can save at any time, save immediately, or just save on a *shutdown* signal.
2023-04-18 01:26:02 +00:00
Therefore, the "filesystem" code will just be a library that's simple a low-level interface for the `kernel` to use.
*Actors* will simply make requests to save.
2023-04-17 23:51:01 +00:00
## Filesystem Layout
### Partition
A virtual section of the disk.
2023-04-18 01:26:02 +00:00
It's identified simply by numerical order.
2023-04-17 23:51:01 +00:00
```rust
2023-04-18 01:26:02 +00:00
const BOOT_SIZE: u64; // How large the BOOT partition will be
const LABEL_SIZE: u64; // Number of characters that can be used in the partition label
2023-04-17 23:51:01 +00:00
struct PartitionHeader {
2023-04-18 01:26:02 +00:00
boot: bool, // Boot flag
label: [char; LABEL_SIZE], // Human-readable label. Not UTF-8 though :/
2023-04-17 23:51:01 +00:00
num_chunks: u64, // Chunks in this partition
}
```
### Chunk
Small pieces that each partition is split into.
2023-04-18 01:26:02 +00:00
Contains fixed-length metadata (checksum, extension flag, uuid) at the beginning, and then arbitrary data afterwards.
If the saved data exceeds past a single chunk, the `extends` flag is set.
Additionally, it has a **UUID** generated via [lolid](https://lib.rs/crates/lolid) to enable identifying a specific chunk.
2023-04-17 23:51:01 +00:00
```rust
2023-04-18 01:26:02 +00:00
const CHUNK_SIZE: u16; // Example static chunk size
2023-04-17 23:51:01 +00:00
struct Chunk {
checksum: u64,
extends: bool,
2023-04-18 03:02:19 +00:00
encrypted: bool,
2023-04-18 01:26:02 +00:00
uuid: Uuid,
data: [u8; CHUNK_SIZE],
2023-04-17 23:51:01 +00:00
}
```
This struct is then encoded into bytes and written to the disk. Drivers for the disk are *to be implemented*.
It *should* be possible to do autodetection, and maybe for *Actors* to specify which disk/partition they want to be saved to.
2023-04-18 01:26:02 +00:00
Compression of the data should also be possible, due to `bincode` supporting [flate2](https://lib.rs/crates/flate2) compression.
2023-04-18 03:02:19 +00:00
Similarely **AES** encryption can be used, and this allows for only specific chunks to be encrypted.[^encryption]
2023-04-18 01:26:02 +00:00
2023-04-17 23:51:01 +00:00
### Reading
On boot, we start executing code from the beginning of the disk (the boot partition, although that's meaningless at this point).
The `kernel` then reads in bytes from the first partition *(as the **BOOT** partition is fixed-size, we know when this starts)* into memory, serializing it into a `PartitionHeader` struct via [bincode](https://lib.rs/crates/bincode).
From here, as we have a fixed `CHUNK_SIZE`, and know how many chunks are in our first partition, we can read from any chunk on any partition now.
On startup, an *Actor* can request to read data from the disk. If it has the right [capabilities](/development/design/actor.md#ocap), we find the chunk it's looking for[^find_chunk], parse the data (using `bincode` again), and send it back.
2023-04-18 11:19:16 +00:00
Also, we are able to verify data. Before passing off the data, we re-hash it using [HighwayHash](https://lib.rs/crates/highway) to see if it matches.
2023-04-17 23:51:01 +00:00
If it does, we simply pass it along like normal. If not, we refuse, and send an error [message](/development/design/actor.md#messages).
### Writing
Writing uses a similar process. An *Actor* can request to write data. If it has proper capabilties, we serialize the data, allocate a free chunk[^free_chunk], and write to it.
We *hash* the data first to generate a checksum, and set proper metadata if the data extends past the `CHUNK_SIZE`.
### Permissions
Again, whether actors can:
- Write to a specific disk/partition
- Write to disk at all
- Read from disk
will be determined via [capabilities](/development/design/actor.md#ocap)
2023-04-18 11:19:16 +00:00
### To-Do
- Snapshots
- Isolation
2023-04-18 03:02:19 +00:00
[^encryption]: Specific details to be figured out later
2023-04-17 23:51:01 +00:00
[^find_chunk]: Currently via magic. I have no idea how to do this other than a simple search. Maybe generate an index, or use a **UUID**?
[^free_chunk]: Again, no idea how.