logo

Process FD Table vs Global Open File Table

In Linux, file management is handled through a three-tier hierarchy. Understanding the difference between the Process FD Table and the Global Open File Table is key to understanding how processes share files and offsets.

The Process File Descriptor Table (Local)

Every process has its own private table of file descriptors.

  • Where it lives: Inside the task_struct (the process control block), specifically in files_struct.
  • What it is: A simple array of pointers.
  • The Index: The array index is the File Descriptor (FD) integer (0, 1, 2, 3...).
  • The Value: Each entry in the array points to an entry in the Global Open File Table.

The Global Open File Table (System-wide)

This table contains "Open File Descriptions." It represents the actual active session of an open file.

  • Where it lives: In kernel memory, shared by all processes.
  • What it is: A list of struct file objects.
  • Key Data Stored Here:
    • File Offset (f_pos): Where the read/write head is currently located.
    • Status Flags: How the file was opened (e.g., O_APPEND, O_CREAT, O_RDONLY).
    • Reference Count: How many FDs across the whole system point to this specific session.
    • VFS Pointers: Pointers to the dentry and inode.

The Comparison

Feature Process FD Table Global Open File Table
Scope Per-Process. Private to you. System-wide. Shared by all.
Entries Integers (0, 1, 2...). struct file objects.
Stores Offset? No. Yes (the shared cursor).
Stores Flags? No (except FD_CLOEXEC). Yes (Read/Write/Append).
Creation When you open(), dup(), or pipe(). When a new open() session starts.

How they work together (The 3-Tier View)

To truly understand this, we must include the Inode Table (the actual data on disk).

Scenario A: Two different processes open the same file

  1. Process A calls open("log.txt").
  2. Process B calls open("log.txt").
  • FD Table: Each process gets its own FD (e.g., FD 3).
  • Global Table: Each gets its own struct file.
  • Inode Table: Both point to the same inode.
  • Result: They have independent offsets. If Process A reads 10 bytes, Process B's cursor stays at 0.

Scenario B: A process forks (Shared Session)

  1. Process A calls open("log.txt").
  2. Process A calls fork(), creating Process B.
  • FD Table: Process B gets a copy of Process A's table.
  • Global Table: Both point to the exact same struct file.
  • Inode Table: Points to the same inode.
  • Result: They share the offset. If the parent reads 10 bytes, the child’s cursor also moves to 10. This is how shells manage standard output for piped commands.

Where is the offset stored?

The offset is stored in the Global Open File Table (specifically in the struct file object).

It is NOT stored in the Process FD Table. The Process FD Table is too "shallow" for that; its only job is to map an integer (like 3) to a pointer in the Global Open File Table.