Module 02 • COSC240

Directories & Path Resolution

Examine how operating systems structure, search, and protect the file system namespace: single-level directories, two-level Master/User architectures, recursive tree hierarchies, structural self/parent links, path resolution, and hard versus symbolic links.

1. Single-Level Directory Systems

To track files stored on secondary storage media, the operating system maintains a mapping between human-readable file names and physical storage locations. The simplest design is a single-level directory system (a flat directory structure).

Architectural Characteristics

Practical Applications & Limitations

Single-level directory systems appeared in early mainframe operating systems and first-generation personal microcomputers, such as early CP/M and original MS-DOS 1.0 on 160 KB / 360 KB 5.25-inch diskettes. With only dozens of files per disk, flat tables were computationally inexpensive.

  1. Name Collisions: In multi-user systems, coordinate naming breaks down, forcing artificial prefixes like alice_prog.c and bob_prog.c.
  2. Project Segmentation Failure: Even for a single user, storing thousands of source modules, binaries, and data records in a single flat list makes cataloging difficult.
  3. Linear Search Bottlenecks: Directory lookup requires scanning an increasingly large linear table ($\mathcal{O}(N)$), driving up disk access latency.
Figure 4-1: Single-Level Flat Directory Layout Root / Master Directory (Flat Table) All users share one namespace | High collision probability file1.txt Blocks: 10, 11 notes.c Blocks: 14, 15 game.exe Blocks: 22, 23 memo.txt Alice's Copy memo.txt COLLISION (Denied)

2. Two-Level Directory Systems

The shift to multi-user time-sharing architectures (such as MIT's CTSS and DEC TOPS-10) demanded isolated namespaces. Operating systems introduced a fixed two-tier hierarchy:

Figure 4-2A: Two-Level Directory Structural Topology (MFD to UFD) Master File Directory (MFD) [ALICE] | [BOB] | [SYSTEM] UFD: ALICE main.c (i-node #108) test.dat (i-node #109) output.log UFD: BOB main.c (i-node #214) project.asm (i-node #215) notes.txt UFD: SYSTEM (SYS:) cc (Compiler binary) ed (Editor binary) as (Assembler binary)

The System Utility & Fallback Search Dilemma

While account segregation prevents conflicts, duplicating common executables (cc, ed, as) across every user's UFD exhausts storage. Systems introduced a dedicated system directory and a Two-Stage Fallback Search Rule:

Two-Stage Search Rule:

$$ \text{SearchTarget} = \begin{cases} \text{Step 1:} & \text{Search Active Caller UFD} \\ \text{Step 2:} & \text{If not found } \longrightarrow \text{Search SYSTEM UFD} \\ \text{Step 3:} & \text{If not found } \longrightarrow \text{Return Error (ENOENT)} \end{cases} $$

3. Hierarchical (Tree-Structured) Directory Systems

Pioneered by Multics and UNIX, the generalization from two tiers to arbitrary depth is straightforward: allow directory entries to point to other directories as well as regular files.

Directories as Specialized Files

Self and Parent Links: . and ..

Every directory created in a hierarchical file system is initialized with two structural entries:

The Root Invariant:

$$ \text{inode}("/..") \equiv \text{inode}("/.") \equiv \text{Root Inode (typically Inode 2)} $$

Traversing above the root cycles back to the root, preventing file system traversal escapes.

Path Name Classification

Path Class Starting Anchor Syntax Signature Example Resolution Mechanics
Absolute Path Root directory (/ or C:\) Leading slash or drive specifier /home/alice/src/main.c MMU/VFS begins traversal unconditionally at the root inode.
Relative Path Current Working Directory (CWD) No leading slash src/main.c or ../bob/notes.txt Traversal begins from the CWD inode recorded in the process PCB.
Hierarchical Tree & Path Resolution Sandbox Tanenbaum §4.2.3
On-Disk Table for: /
Name Type i-node Notes
$ session started. Active working directory set to /
/ $
Quick Jumps:

4. Directory System Calls & Link Mechanics

Interactive Walkthrough: Directory Operations & Link-Count Lifecycle
Trace step-by-step how the kernel updates directory blocks, enforces the emptiness invariant, tracks reference counts, and reclaims disk blocks.
Step 1: Directory Created. Kernel executes mkdir("/home/project"). Allocates directory inode #115 and formats initial . and .. entries.
Phase: 1/5
Target Inode: #115 (DIR)
Link Count: nlink = 2
Storage: 1 Block
Synchronized Visual Canvas — Directory Table & Inode Blocks
DIR TABLE: /home/project . → Inode #115 (Self) .. → Inode #4 (Parent) [Unallocated Slot 2] [Unallocated Slot 3] INODE METADATA RECORD Inode #120 (Regular) nlink = 0 Blocks: 0 UNALLOCATED
Status: Directory /home/project formatted with . and ..
🔍 What Is Happening
The kernel allocates directory inode #115 and immediately formats data block with entries . (self) and .. (parent).
⚙ Why The System Does This
Directories are never truly empty; self and parent bindings guarantee that relative path resolution works recursively across all subtrees.