realchonk / fuse-ufs

FUSE driver for FreeBSD's UFSv2
BSD 2-Clause "Simplified" License
4 stars 2 forks source link

Metadata caching #34

Open asomers opened 2 months ago

asomers commented 2 months ago

The current implementation of fuse-ufs reads file blocks on an as-needed basis. So it uses very little RAM. But an unintended result is that for many read-world workloads, fuse-ufs will read the same blocks from disk over and over. For example, if the user tries to read an entire large file, resolve_file_block will reread every indirect block from disk for each block in the file. For a file with one level of indirection, that basically doubles the amount of disk activity relative to an efficient implementation.

An efficient implementation would cache metadata in RAM. A full-featured cache might include an LRU or even an ARC to limit the cache's size. But two facts make fuse-ufs's job easier:

So an easy way to handle cacheing would be for fuse-ufs to keep a container of open Inode objects. The lookup method will add objects to that container, and forget will remove them. Then operations like read would cache the inode's indirect blocks within the Inode object itself. For directories, readdir would do the same.

Here is an example of a benchmark program that computes the read amplification of various operations for a similar fuse file system. It would be easy to adapt to fuse-ufs. https://github.com/KhaledEmaraDev/xfuse/blob/b6ad7fd32ad4443b5ab4ab684ae0c7639eb31be1/benches/read-amplification.rs

realchonk commented 2 months ago

I agree. I have even done something like that before, so it's nothing new to me.

realchonk commented 2 months ago

Blocked by #41