Skip to content
Path Resolution
step 1/5

Reading — step 1 of 5

Read

~1 min readDirectories & Paths

Path Resolution

Resolve /home/alice/notes.txt:

  1. Start at root inode (always inode 2 for ext, or 1 in xv6).
  2. Read root directory data → look up "home" → inode N.
  3. Load inode N. Read its data → look up "alice" → inode M.
  4. Load M. Read → look up "notes.txt" → inode K.
  5. Load K. Done.
struct inode *namei(char *path) {
    struct inode *ip = root;
    while (path && *path) {
        char component[NAME_MAX];
        path = parse_component(path, component);
        if (ip->type != DIR) return ENOTDIR;
        ip = dir_lookup(ip, component);
        if (!ip) return ENOENT;
    }
    return ip;
}

Cache: dentry cache (Linux) caches path → inode mappings. Fast repeated lookups (e.g., /usr/lib/... accessed often).

Symlinks:

  • During walk, if encountered: read target path, recurse from current dir (or root for absolute).
  • Loop detection: bound the depth (e.g., 40 for Linux).

Mount points:

  • Inode for mount target appears as the mounted FS's root.
  • chdir into mounted FS: now in different inode space.

Relative vs absolute paths:

  • Absolute starts with /: from root.
  • Relative: from cwd (current working directory of process).

. and ..:

  • . = current dir.
  • .. = parent dir.
  • Resolved during walk by directory's own entries.

Performance:

  • Each path component = 1 inode read + 1 directory read.
  • Deep paths: many I/Os.
  • Dentry cache: a hit avoids the I/O.
  • Negative cache: "this name doesn't exist" cached too.

Concurrency:

  • Renaming a directory mid-walk: might break.
  • Locking per-inode during lookup.
  • Linux uses RCU walks for fast lock-free path resolution.

Path canonicalization (realpath):

  • Resolve symlinks at every step.
  • Get absolute, symlink-free path.
  • Used for security checks (don't trust paths).

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…