100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C

Directory Structures

How file systems organize files into single-level, two-level, tree, and acyclic-graph directory hierarchies.

File SystemsIntermediate8 min readJul 8, 2026
Analogies

Introduction

A directory is itself a special kind of file that maps file names to their metadata (or inode numbers), allowing the operating system to organize potentially thousands of files in a way users and programs can navigate. The structure chosen for organizing directories affects how files are named, how naming conflicts are avoided, and how flexibly files can be shared between users.

🏏

Cricket analogy: A tournament fixture sheet maps each team name to its group, venue, and match schedule, letting organizers and fans navigate hundreds of matches without memorizing raw ground codes.

Explanation

In a single-level directory, all files for all users exist in one flat namespace. It is simple to implement but every file name across the entire system must be unique, which quickly becomes unworkable with multiple users or many files. The two-level directory structure gives each user their own separate directory, so users can reuse the same file name without conflict; however, it does not naturally support grouping a user's own files into categories, and sharing files between users requires special path notation to reach into another user's directory. The tree-structured directory generalizes this into an arbitrary hierarchy: each user (or the root) can create subdirectories nested to any depth, files are located via absolute paths (from the root) or relative paths (from the current working directory), and the current-directory concept lets users navigate the tree efficiently. A tree forbids cycles by construction (each node has exactly one parent), which simplifies deletion and traversal but makes sharing a file between two different directories awkward, since a true tree only allows one path to any given file. The acyclic-graph directory structure relaxes this by allowing a file (or subdirectory) to have multiple parent directories via links (hard links or symbolic links), so the same physical file can appear under several different directory paths -- useful for shared libraries or collaborative files -- while still disallowing cycles (a directory cannot ultimately point back to itself), because cycles would break simple reference-counting deletion and could cause infinite loops during directory traversal.

🏏

Cricket analogy: A single scorebook shared by every league in a city (single-level) forces every player's name to be unique citywide; giving each team its own scorebook (two-level) fixes that, and letting each team further organize by season and format (tree) with a shared coach's file linked into two teams' books (acyclic graph) mirrors real club administration.

Example

c
#include <unistd.h>
#include <stdio.h>

int main(void) {
    /* Create a hard link: "report_copy.txt" now shares the SAME
       inode as "report.txt" -- this is exactly what makes a
       tree-structured directory into an acyclic-graph directory,
       since the same file now has two parent directory entries. */
    if (link("report.txt", "report_copy.txt") == -1) {
        perror("link");
        return 1;
    }

    /* Create a symbolic link: a separate small file that merely
       stores the path "report.txt" and is resolved at access time. */
    if (symlink("report.txt", "report_symlink.txt") == -1) {
        perror("symlink");
        return 1;
    }

    printf("Both report_copy.txt (hard link) and "
           "report_symlink.txt (symlink) now reference report.txt\n");
    return 0;
}

Analysis

link() creates a hard link: a second directory entry pointing at the same inode number, incrementing the inode's link count; the file's data is only freed once the link count reaches zero and no process still has it open. This is precisely how a tree becomes an acyclic graph -- the same inode now has two parents (two directory entries), so it is no longer reachable by only one path. symlink() instead creates a new, separate inode whose data is just a path string that the OS resolves (follows) when accessed; if the target is deleted, the symlink becomes a dangling reference. Both mechanisms enable file sharing across directories, but the file system must still detect and reject attempts to create a cycle (e.g., a directory linked into one of its own descendants), typically by disallowing hard links to directories and by bounding symlink resolution to avoid infinite loops.

🏏

Cricket analogy: A player's name appearing on both the "top scorers" and "player of the match" honor boards is like a hard link -- one real achievement referenced from two lists, still counted once; a poster merely pointing to "see honor board" is like a symlink, and if the board is taken down the poster points nowhere.

Key Takeaways

  • Single-level directory: one flat namespace shared by everyone; simple but names must be globally unique.
  • Two-level directory: one directory per user avoids name clashes across users but complicates cross-user sharing and offers no sub-grouping.
  • Tree-structured directory: arbitrary nested subdirectories, navigated via absolute/relative paths and a current-directory pointer; each file has exactly one path.
  • Acyclic-graph directory: allows shared files/subdirectories via hard or symbolic links (multiple parents) while still forbidding cycles.
  • Cycles are avoided because they would break simple link-count-based deletion and could cause infinite loops during traversal.

Practice what you learned

Was this page helpful?

Topics covered

#OperatingSystemsStudyNotes#OperatingSystems#DirectoryStructures#Directory#Structures#Explanation#Example#StudyNotes#SkillVeris#ExamPrep