In operating systems, filesystems describe the mechanisms which OS store and manage files. Most modern filesystems are stored as a directed acrylic graph (or tree).
Absolute paths are the full paths starting from the root directory. Relative paths are relative to the current working directory.
We can access files sequentially or randomly
- Sequential access
- Each read advances the position inside the file
- writes are appended and position set to the end after
- Random access
- can be read/written to in any order, requires position
how do we store files?
- linked allocation (with lists)
- slow random access
- only start block needs to be stored, need to store pointer to next block
- files can grow/shrink without external fragmentation
- but with internal fragmentation
- slow, need to walk each block
- each block might be far away and it won’t be cached
- File allocation table (FAT)
- moves linked lists to a separate table
- FAT32: size of ptr
- same grow/shrink idea as linked allocation
- no external frag, yes internal frag
- fast random access (so FAT can be held in cache)
- FAT size linear to disk size, can become very large
- indexed allocation: maps each block directly
- each block maps to a block in physical storage
- like a single level page table
block table 8 kB (page size) pointer 4 B (PTE)
how big a file can we represent? == number pointers per block = times block size = == 16 MB
filesystem Cache
- writing data to the disk is slow
- temporal and spatial locality for file blocks
- kernel thread (daemon) writes changes periodically to disk
flush
andsync
syscall trigger a permanent write, i.e., flushing the buffer
deleting file in a journaling filesystem
- removing directory entry
- releasing inode into pool of free inodes
- returning all disk blocks to the pool of free disk blocks
- crashes could occur between any step, leading to a storage leak
- journal contains operations in progress so can recover if a crash occurs
inodes: much better flexibility over contiguous, linked, FAT, or indexed