Skip to content

Commit ffbe2d5

Browse files
committed
initial commit
1 parent d03a39e commit ffbe2d5

File tree

12 files changed

+515
-6
lines changed

12 files changed

+515
-6
lines changed

.gitignore

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
# Generated by Cargo
22
# will have compiled files and executables
33
debug/
4-
target/
5-
6-
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7-
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
8-
Cargo.lock
94

105
# These are backup files generated by rustfmt
116
**/*.rs.bk
@@ -18,4 +13,6 @@ Cargo.lock
1813
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
1914
# and can be added to the global gitignore or merged into this file. For a more nuclear
2015
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
21-
#.idea/
16+
#.idea/
17+
/target
18+
*.img

Cargo.lock

+201
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "tinyFS"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
fuse = "0.3.1"
8+
bincode = "1.3.3"
9+
bitvec = "1"
10+
serde = { version = "1", features = ["derive"] }

design/img/disk.png

30.8 KB
Loading

design/mkfs.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## mkfs
2+
3+
mkfs formats the disk with a particular format

design/tinyfs.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
2+
## TinyFS
3+
TinyFS is a small and simple FUSE based filesystem created mainly for educational purposes and has no ambition of
4+
becoming a production ready filesystem. TinyFS will be implemented in Rust.
5+
6+
### Goals
7+
- Support **mkfs** to create the disk layout
8+
- Support the following file operations
9+
- **open** filename flag
10+
- **read** fd size
11+
- **write** fd string
12+
- **seek** fd offset
13+
- **close** fd
14+
- **mkdir** dirname
15+
- **rmdir** dirname
16+
- **cd** dirname
17+
- **ls**
18+
- **cat**
19+
- **tree**
20+
21+
22+
23+
### Non Goals
24+
- Support Journaling
25+
- Supporting large files
26+
- Becoming a distributed filesystem
27+
28+
29+
## Design
30+
31+
### Disk Layout
32+
33+
TinyFS formats the disk into 4kb blocks and will have 64 blocks in total, which means that TinyFS requires a disk with
34+
256mb free space. The first block will be used for the superblock, the next two blocks will be used for inode and data
35+
bitmap tables respectively and the following 5 blocks are used for inodes.
36+
37+
<figure>
38+
39+
![Disk](img/disk.png)
40+
41+
<figcaption align="center">TinyFS Disk Layout</figcaption>
42+
43+
</figure>
44+
45+
The disk layout above means that the first 8 blocks are used for managing the filesystem and the remaining 56 blocks are
46+
used for actual data storage.
47+
48+
### Datastructures
49+
50+
#### Superblock
51+
52+
Superblock contains metadata about the filesystem. TinyFS reads the superblock on initialization to know things like
53+
how much disk space is remaing.
54+
55+
```
56+
Superblock
57+
block_size int
58+
block_count int
59+
```
60+
61+
#### Bitmaps
62+
63+
A bitmap is an array of bytes used to indicate whether the corresponding block is free or allocated. Each bit in the array
64+
maps to a corresponding block. Bit 0 maps to block 0, bit 1 maps to block 1 so on and so forth.
65+
66+
```
67+
Bitmap
68+
[]byte
69+
```
70+
71+
#### Inodes
72+
73+
Inodes hold file metadata and represent both files and directories
74+
75+
```
76+
Inode
77+
mode int
78+
uid int
79+
gid int
80+
size int
81+
created_at Time
82+
modified_at Time
83+
deleted_at Time
84+
flags byte
85+
hard_links int
86+
direct_blocks []int
87+
indirect_block []int
88+
double_indirect_block []int
89+
```
90+
91+
92+
#### Data Blocks
93+
94+
Datablocks have no particular structure and hold the actual file data.
95+
96+
## Implementation
97+
98+
[mkfs](./mkfs.md)
99+
100+
## Notes
101+
Before mounting the FS, make sure that the directory exists ie `mkdir /tmp/tiny`
102+
103+
To unmount the fs, `fusermount -u /tmp/tiny`
104+
105+
When permissions are denied use `sudo addgroup <USERNAME> fuse`
106+
107+
## References
108+
109+
[Filesystem Implementation](https://pages.cs.wisc.edu/~remzi/OSTEP/file-implementation.pdf)

src/main.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
mod mkfs;
2+
mod tiny;
3+
4+
use fuse::Filesystem;
5+
6+
fn main() {
7+
mkfs::make("./tiny.img");
8+
9+
let mount_path = "/tmp/tiny";
10+
fuse::mount(TinyFS, &mount_path, &[]).expect("expected filesytem to mount");
11+
}
12+
13+
struct TinyFS;
14+
15+
impl Filesystem for TinyFS {}

src/mkfs.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use std::{
2+
fs::OpenOptions,
3+
io::{BufWriter, Write},
4+
};
5+
6+
use crate::tiny::{
7+
bitmap::Bitmap,
8+
inode::InodeTable,
9+
superblock::{Superblock, BLOCK_SIZE},
10+
};
11+
12+
pub fn make(path: &str) {
13+
let file = OpenOptions::new()
14+
.write(true)
15+
.create_new(true)
16+
.open(path)
17+
.expect("file to have been opened");
18+
19+
let mut buf = BufWriter::new(&file);
20+
21+
let mut super_block = Superblock::new(BLOCK_SIZE, 64);
22+
super_block.serialize_into(&mut buf);
23+
24+
let mut bitmap = Bitmap::new();
25+
bitmap.serialize_into(&mut buf);
26+
27+
let mut inode_table = InodeTable::new(5);
28+
inode_table.serialize_into(&mut buf);
29+
30+
buf.flush().expect("buffer to have been flushed");
31+
file.set_len(64 * BLOCK_SIZE)
32+
.expect("to have set file size");
33+
}

0 commit comments

Comments
 (0)