Add basic filesystem ideas writeup
parent
1240f06279
commit
3b763fdad9
|
@ -8,7 +8,7 @@
|
||||||
- [Security Features]()
|
- [Security Features]()
|
||||||
- [Microkernel]()
|
- [Microkernel]()
|
||||||
- [GUI]()
|
- [GUI]()
|
||||||
- [Filesystem]()
|
- [Filesystem](development/design/filesystem.md)
|
||||||
- [Configuring a Build Environment](development/environment.md)
|
- [Configuring a Build Environment](development/environment.md)
|
||||||
- [Development Workflow](development/workflow.md)
|
- [Development Workflow](development/workflow.md)
|
||||||
- [Using the OS](user/README.md)
|
- [Using the OS](user/README.md)
|
||||||
|
|
|
@ -1 +1,75 @@
|
||||||
# Filesystem
|
# Filesystem
|
||||||
|
```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.
|
||||||
|
|
||||||
|
Therefore, the "filesystem" code will just be a library that's simple a low-level interface for actors to use.
|
||||||
|
|
||||||
|
|
||||||
|
## Filesystem Layout
|
||||||
|
### Partition
|
||||||
|
A virtual section of the disk.
|
||||||
|
- **BOOT Partition:** Fixed-size partition at the beginning of the disk, containing the kernel code, and info about the other partitions.
|
||||||
|
- **DATA Partition:** Fixed-size partition containing misc. *Actor* data
|
||||||
|
- **USER Partition:** Contains all data from the `User` [namespace](/development/design/actor.md#namespaces)
|
||||||
|
```rust
|
||||||
|
enum PartitionLabel {
|
||||||
|
Boot,
|
||||||
|
Data,
|
||||||
|
User,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PartitionHeader {
|
||||||
|
label: PartitionLabel,
|
||||||
|
num_chunks: u64, // Chunks in this partition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chunk
|
||||||
|
Small pieces that each partition is split into.
|
||||||
|
Contains fixed-length metadata (checksum, dates) at the beginning, and then arbitrary data afterwards.
|
||||||
|
If the saved data exceeds past a single chunk, the metadata lists this.
|
||||||
|
```rust
|
||||||
|
struct Chunk {
|
||||||
|
checksum: u64,
|
||||||
|
extends: bool,
|
||||||
|
data: [u8; 512],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
Also, we are able to verify data. Before passing off the data, we re-hash it using [ahash](https://lib.rs/crates/ahash) to see if it matches.
|
||||||
|
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)
|
||||||
|
|
||||||
|
[^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.
|
||||||
|
|
Loading…
Reference in New Issue