Skip to content

jnin-dev/Simple-LogFS

Repository files navigation

Simple Log File System

This was a project to learn more about how file systems are implemented and managed on operating systems. Using a virtual disk and a custom shell, it runs a file system on the virtual disk to format, create, delete, mount, unmount, read, and write the files on the filesystem in the virtual disk. Blank diagram(4)

Compilation

"make simplefs" to create our file system. You can run it using "./simplefs <file_name> "

  • file_name is a custom disk "image.x" on this project or using your own file by creating a blank file.
    • If you do opt for your own file, you can create an empty file "touch <file_name>"
  • nblocks is the amount of blocks for our disk.

Usage

$ help # Gives a list of commands
$ format # Run this first to format the filesystem
$ mount # Run this next to mount our filesystem
$ unmount # Unmounts the fs
$ debug # Metadata of the filesystem
$ create # Creates an inode which can be used to copy data into it or out of it
$ delete <inode> # Deletes an inode
$ getsize <inode> # Gets the size of data inside the inode
$ cat <inode> # View contents of the inode
$ copyin <file> <inode> # Copy contents of a file to an inode
$ copyout <inode> <file> # Copy inode contents to a file
$ quit/exit

Example usage

echo "HELLO WORLD\n" > hello.txt
touch myFileSystem 20
./simplefs 
$ format
$ mount
$ create
Block num: 1
created inode 0
$ create
Block num: 1
created inode 1
$ copyin hello.txt 1
14 bytes copied
copied file hello.txt to inode 1
$ cat 1
HELLO WORLD\n
$

Disk

disk.c and disk.h is the implementation of the disk. It opens a file for reading or writing. It truncates the file into block sizes to emulate our disk.

Shell

shell.c is a simple implementation of a shell. It does not utilize exec or fork to create a separate process for the shell but just runs in the current shell. It receives commands to run within the file system.

File System

fs.c and fs.h are the implementation of our file system. It contains a superblock which acts as either the superblock, an inode, indirect block, or data block using union. The layout of the file system is

<superblock>|<direct_inodes>|<indirect_inodes>|<data_blocks>

fs_format() clears out the inode table, data table, and inits our superblock

fs_mount() allocates our superblock, inodes, and freemap which is used to find which blocks to clean up

fs_create() creates an inode within a data block to hold data

fs_delete() clears out the inode

fs_read() opens a data block to read using our inode number.

fs_write() opens data block to write using our inode number.

What I've Learned

Through this project I've learned how file systems are implemented but also edge cases managed. For example what if we don't write the entirety of the inode? How do we deal with internal and external fragmentation? What if someone attempts to create more inodes than can be fit in a data block? How can we ensure that if someone writes beyond the size of an inode that we don't cause memory access problems?

While fragmentation is still a problem with this project, we've dealt with a few edge cases. First with writing > inode size, we cut off whatever was copied. Another thing is concatenating multiple inodes in order to copyout the contents to a file.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors