04. Management & Optimization

Tanenbaum Chapter 4.4: Block Allocation Economics, Backup Architectures, and Multi-Dimensional Consistency Verification.

4.4.1 File-System Space Management

Files can be stored using contiguous allocation or dynamic block-based allocation. Nearly all general-purpose filesystems divide storage media into fixed-size logical blocks. Choosing how large those blocks should be, how to track available free space, and how to enforce equitable storage limits across users represents a core systems optimization challenge.

1. The Block Size Selection Dilemma

Storage drives physically transfer data in sectors (typically 512 bytes or 4096 bytes). Operating system file systems group multiple contiguous sectors into a single logical block. The choice of block size involves an inescapable engineering trade-off:

Empirical studies across Unix distributions demonstrate that the median file size typically sits between 2 KB and 4 KB. Consequently, modern desktop and server filesystems (such as ext4 and NTFS) standardize on 4 KB blocks as the optimal equilibrium between internal fragmentation waste and transfer rate efficiency.

Interactive Simulator: Block Size vs. Internal Fragmentation Active Size: 4 KB
Evaluate Allocation Efficiency: Observe how switching block sizes affects internal fragmentation across a realistic workload of 10 mixed files (median size: 3.2 KB).
Total Data: 32 KB across 10 files. Disk Consumed: 48 KB | Wasted Space: 16 KB (33% waste)

2. Tracking Free Blocks: Linked Lists vs. Bitmaps

To allocate space for new files, the filesystem must track every unallocated block on storage media. Two primary data structures dominate:

Approach A: The Linked Free List

Free blocks are chained together. Rather than linking blocks individually (which would require seeking to every single block just to find the next), filesystems use a Grouped Linked List:

Approach B: The Bitmap (Bit Vector)

A dedicated allocation map represents the filesystem partition as an array of bits, where each bit corresponds to a single logical block: 0 indicates a free block, and 1 indicates an allocated block.

Figure 4.4.1: Free Space Management (Linked Free List vs. Allocation Bitmap) Grouped Linked Free List Disk Block #16 [#17, #18, #19, ...] Next → Block #240 Disk Block #240 [#241, #242, ...] Next → NULL Only active head block must reside in RAM Contiguous Allocation Bitmap 1 1 0 0 0 1 0 Contiguous Free Span Detected: Blocks 2, 3, 4 1 bit per block • 32 MB tracks 1 TB drive
Figure 4.4.1: Linked lists minimize active memory overhead, while bitmaps enable instant contiguous searches.

3. Disk Quotas

Multi-user operating systems prevent rogue users or buggy processes from exhausting disk capacity via Disk Quotas. Quotas track two distinct resource metrics per user or group:

Quotas establish two threshold limits:

4.4.2 File-System Backups

Hardware components inevitably fail, storage drives wear out, and human operators accidentally execute destructive commands. Designing resilient backup procedures requires balancing backup window durations against recovery time objectives.

1. Physical vs. Logical Dumps

Storage architectures use two primary methodologies to extract backup copies:

2. Full vs. Incremental Dump Strategies

Executing a complete, full backup of an enterprise storage cluster every single night is rarely feasible in practice. The physical backup window (the maintenance period during which user modifications must be frozen or minimized) is too short, and the sheer volume of data exceeds available network and tape bandwidth. To solve this, storage administrators deploy a hierarchical Incremental Dump Strategy combining base references with delta captures.

The Backup Level Hierarchy

Unix and Linux backup architectures (historically instantiated by the dump utility) organize backups into hierarchical numeric Dump Levels ranging from Level 0 to Level 9:

Concrete Weekly Schedule Example: Consider a standard enterprise rotation operating across a seven-day cycle:

Tracking Changes & The Recovery Trade-off

To determine whether a file requires archiving during an incremental run, the backup utility compares the file's last modified timestamp (mtime / ctime) against the timestamp embedded in the metadata header of the previous reference backup level. Furthermore, directory change markers trigger the Four-Pass Traversal Algorithm (Scanning inodes, marking ancestor directories, dumping directory structures, and streaming modified file data blocks).

While incremental strategies minimize nightly backup windows, they introduce an inverse penalty during Disaster Recovery. Restoring from a Level 0 full dump requires only a single tape; restoring from an incremental chain requires a multi-step restoration cascade (Level 0 + Level 1 + Level 2 + Level 2). If any single incremental tape in the chain is damaged, restoration fails.

Figure 4.4.2B: Multi-Tape Disaster Recovery & Incremental Restoration Cascade Step 1: Sunday Level 0 (Full) Baseline Foundation Step 2: Monday Level 1 (Delta) Overlay Mon Changes Step 3: Tuesday Level 2 (Delta) Overlay Tue Changes Step 4: Wednesday Level 2 (Missing Tape!) ✗ Chain Fails ✗ Disaster Recovery Risk: A single missing or corrupted incremental tape breaks the entire restoration chain!
Figure 4.4.2B: The multi-tape restoration dependency chain required when executing incremental recoveries.

3. Consistency During Live Backups: Snapshots

If an incremental dump executes on a live filesystem, users and background daemons continue writing to files. If a user moves a file from directory /A to directory /B while the backup is traversing /B, the file may either be dumped twice or skipped completely, leaving an inconsistent backup archive.

Modern storage architectures resolve this using Filesystem Snapshots (supported by LVM, ZFS, and Btrfs). A snapshot creates a frozen, read-only logical view of the volume at an exact point in time. When blocks are modified post-snapshot, the underlying driver uses Copy-on-Write (CoW): preserving the original block in a snapshot region while writing updates to a new block. The backup utility walks the frozen snapshot view without freezing user applications or risking corruption.

4.4.3 File-System Consistency

When an unjournaled filesystem crashes (or when hardware bit rot corrupts a journaled filesystem), the operating system runs an integrity checking utility upon reboot (such as fsck in Unix or chkdsk in Windows).

The integrity checker performs a comprehensive Two-Dimensional Audit: validating physical block allocations against logical filesystem references, and validating directory entry trees against inode link counts.

1. Block Consistency Audits

The checker builds two independent tracking arrays in memory:

The checker reads every inode. For each direct and indirect pointer, it increments Track_Block[B]. It then inspects the free list or bitmap. In a healthy filesystem, every block on disk must satisfy mutually exclusive parity: it must either be referenced by exactly one inode ($1$) or marked free ($0$). Discrepancies generate four critical error states:

State Tracked Inodes Free Bitmap Failure Nature & Automated Repair Action
Consistent 1 0 (Allocated) Normal state. Block belongs to exactly one file.
Consistent 0 1 (Free) Normal state. Block is unallocated and in the free pool.
Missing Block 0 0 (Allocated) Space Leak: Block is not claimed by any file, but marked occupied in bitmap.
Repair: Toggle the bitmap bit to free ($1$), restoring wasted disk space.
Free List Theft 1 1 (Free) Imminent Corruption: File is using block, but bitmap marks it free. Next write will overwrite file!
Repair: Mark block occupied ($0$) in bitmap.
Duplicate Allocation > 1 0 (Allocated) Cross-Allocation: Two or more files point to the exact same block.
Repair: Allocate a clean block, copy contents, and point one file to the clone.

2. Directory & Link Count Audits

The second dimension validates directory tree linkages against inode metadata. The checker initializes a counter array Link_Count[I]:

  1. Start at the filesystem root directory (inode 2).
  2. Walk all directory entries recursively, incrementing Link_Count[I] every time an entry references inode I.
  3. Compare Link_Count[I] against the inode's internal hard link counter (inode.i_nlink).

Two discrepancies can occur:

Figure 4.4.3: Multi-Dimensional fsck Consistency Verification & Repair Dimension 1: Block Allocation Audit Block #400 Inodes: 1 • Free: 0 ✓ Block #401 (Leak) Inodes: 0 • Free: 0 ✗ Block #402 (Cross) Inodes: 2 • Free: 0 ✗ Repair: Block 401 → Free; Block 402 → Clone to new block Dimension 2: Directory & Link Audit Inode #82 (Orphaned) Dirs: 0 • i_nlink: 1 ✗ /lost+found Re-linked into tree ✓ Repair: Re-connect orphan; align i_nlink to match tree
Figure 4.4.3: The two-dimensional consistency check auditing block counts and directory tree references.
Walkthrough: Interactive FSCK Repair Simulator Audit Status: Idle
Interactive Integrity Audit: Inject structural filesystem errors (missing block space leaks, duplicate block allocations, and orphaned inodes), then execute an automated fsck audit to detect and repair the damage.
Volume healthy. No integrity errors detected. Leaks: 0 | Duplicates: 0 | Orphans: 0