Fast File System (FFS)

CSCI 333 : Storage Systems

Spring 2021

Learning Objectives

Overview of Concepts

The Fast File System (FFS) was developed as an alternative to the poorly performing default Unix file system. FFS employed a number of heuristics that were designed to take advantage of the performance characteristics of hard disk drives. We should know these well: * I/Os require a setup cost to move the disk head and locate it above the first meaningful byte on the platter, followed by * a transfer, where useful bytes are read from the platter Since setup (seeking + rotational delay) is wasted work, FFS tries to minimize the required work to setup an I/O.

FFS focuses on allocation and placement policies that try to minimize fragmentation.

The text identifies at least 3 problems that FFS attempts to solve

  1. Data and metadata separation. Dependent reads require (potentially long) seeks.
  2. Fragmentation of free space
  3. Small block sizes (transfer units)

cylinder/block groups

In the old days, disks were addressed using cylinder-head-sector addressing. This is no longer the case. Now disks are addressed using LBAs.

(You will find nothing in disk specs that say block groups correspond to cylinder groups, but this is likely the case.)

Questions:

  1. What metadata structures does FFS use?
  2. How does FFS use cylinder groups to organize it’s on-disk data? (What data structures are placed where?)

FFS Policies

The FFS policies are a series of heuristics that aspire to, as often as possible, place related objects together. They are heuristics because they make no guarantees. We must hope that they continue to perform well over time.

Placing Files and Directories

To allocate a new directory:

To allocate a new file:

Questions:

  1. How does the directory allocation heuristic affect the relative placement of two directories with a parent child relationship?
  2. How does the file allocation heuristic affect the relative placement of a directory and a regular file with parent child relationship?
  3. How does the file allocation heuristic affect the relative placement of a two files or directories with sibling relationships?
  4. How do the file and directory placement heuristics (as described above) relate to file system growth (creating new files and directories).
  5. What happens to locality when a file is moved from one directory to another?
  6. What locality guarantees are provided when a hard link is created?

Large Things

FFS breaks ranges of file blocks into chunks, and spreads those chunks among different block groups. The first “chunk” contains all of the blocks that are referenced by direct pointers in the inode. Each subsequent chunk is a contiguous range of blocks referenced by the direct pointers in some indirect block. Thus, FFS will attempt to allocate the first handful of blocks (~12) of a file f in the same block group. When the f grows to hold more blocks than can be addressed by direct pointers, FFS will create an indirect block and try to allocate all blocks referenced by that indirect block within the same block group (but a different block group than blocks 0-11). Although f’s blocks are spread among block groups, large chunks of consecutive blocks are kept together. This lets us amortize each seek across an entire chunk of data.

Small Things

FFS has the ability to split data into units that are smaller than a physical disk block.

Thoughts

The FFS goal is to keep related things together. Yet only certain notions of related are prioritized.

  1. When you perform a recursive directory traversal (perhaps grep -r "somestring" .), what order do you traverse the file system namespace?
  2. What seek behavior does that traversal order result in on FFS?

FFS does a lot of work to place data/metadata according to its heuristics.

  1. Does FFS do any work to maintain its locality goals after initial allocation?
  2. What happens if you rename a file? Create a hard link? Delete a file?