Skip to content

A deep dive into Linux File System Internals

Section I: The Anatomy of a Linux File: A Foundational View

Section titled “Section I: The Anatomy of a Linux File: A Foundational View”

At the heart of the Linux operating system lies a simple but powerful philosophy: “everything is a file.” From text documents and executable programs to hardware devices and network connections, all are represented as file-like objects within a unified namespace. To truly master Linux for system debugging and tool development, one must first deconstruct this fundamental concept. A “file” is not a monolithic entity but a composite of distinct components: a name, its associated metadata, and the actual data content. The separation of these elements is the architectural cornerstone upon which the entire filesystem is built, enabling everything from complex permission models to the mechanics of file deletion and recovery.

1.1 Dissecting the ls -l Output: More Than Just a Listing

Section titled “1.1 Dissecting the ls -l Output: More Than Just a Listing”

The primary user-space tool for inspecting a file’s attributes is the ls -l command.1 Its output, while dense, is a structured summary of the most critical metadata associated with a file. Each field corresponds directly to an attribute stored by the filesystem, providing a window into the file’s properties and state.

Consider the following example output:

Terminal window
-rwxr-xr-x 1 user group 4096 Jan 1 12:00 report.txt

This single line can be deconstructed field by field:

  • File Type: The first character - indicates the type of file. This can be a regular file -, a directory d, a symbolic link l, a block device b, a character device c, a named pipe p, or a socket s.2
  • Permission String: The next nine characters (rwxr-xr-x) represent the file’s access permissions, broken into three sets of three for the owner aka user, the group, and other, respectively.1
  • Hard Link Count: The number following the permissions 1 indicates how many hard links, or directory entries, point to this file’s underlying data structure.1
  • Owner (User): The username of the file’s owner (user).1
  • Group: The name of the group associated with the file (group).1
  • File Size: The size of the file in bytes (4096).3 For directories, this number typically reflects the space used to store the list of its contents, not the cumulative size of the files within it. For device files, this field displays the major and minor device numbers instead of a size.4
  • Timestamp: By default, this is the time of the file’s last modification (Jan 1 12:00).3
  • File Name: The final field is the name of the file as it appears in the directory (report.txt).3

This command is not merely a listing tool; it functions as a user-friendly parser for the filesystem’s core metadata structures. Every piece of information it displays, with the sole exception of the filename itself, is read directly from a dedicated data structure that represents the file on disk.

1.2 Metadata vs. Data: The Central Role of the Inode

Section titled “1.2 Metadata vs. Data: The Central Role of the Inode”

The most crucial architectural distinction within a Linux filesystem is the separation between a file’s name and its metadata. The name is simply a label stored within a directory’s contents. All other metadata—everything from permissions to timestamps—is stored in a separate data structure called an inode (index node).5

An inode is the filesystem’s definitive record for a file or directory. It contains all information about the object except its name and its actual data content. The key attributes stored within an inode include:

  • File mode (which specifies the file type and access permissions)
  • Owner and group IDs (UID and GID)
  • File size in bytes
  • Timestamps for last access (atime), last modification (mtime), and last status change (ctime)
  • A count of the number of hard links pointing to the inode
  • Pointers to the physical disk blocks where the file’s actual data is stored.6

This design choice, separating the name from the metadata, has profound consequences. It means a file is not a single object but an abstraction representing the relationship between a directory entry (a name-to-inode-number mapping) and an inode. This indirection is what makes advanced features like hard links possible and is fundamental to understanding the process of file deletion.

1.3 The Structure of File Attributes and Where They Are Stored

Section titled “1.3 The Structure of File Attributes and Where They Are Stored”

The primary file attributes are stored within the inode in a bitmask field known as the mode. This single numeric value efficiently encodes the file’s type and its full set of permissions.7 A standard 16-bit mode is typically structured as follows:

  • File Type (4 bits): The highest-order bits specify the file type (e.g., S_IFREG for a regular file, S_IFDIR for a directory, S_IFLNK for a symbolic link). This code is what ls -l translates into the first character of its output.8
  • Special Permissions (3 bits): The next three bits are dedicated to the special permissions: the set-user-ID (SUID) bit, the set-group-ID (SGID) bit, and the sticky bit.7
  • Standard Permissions (9 bits): The final nine bits encode the standard read, write, and execute permissions for the user, group, and other classes, respectively.7

While the inode’s mode field covers the standard POSIX attributes, modern filesystems like ext4 and XFS also support extended attributes (xattrs). These are arbitrary name-value pairs that can be associated with a file or directory, allowing for a richer set of metadata beyond what the inode structure provides. Extended attributes are used to implement features like Access Control Lists (ACLs) and to store security contexts for systems like SELinux.9 The presence of these attributes is often indicated by a special character (+ or @) at the end of the permission string in the ls -l output on some systems.7

1.4 Understanding the Executable and Linkable Format (ELF)

Section titled “1.4 Understanding the Executable and Linkable Format (ELF)”

For files that are executable programs, the data content itself is not an arbitrary stream of bytes but is structured according to the Executable and Linkable Format (ELF). This is the standard binary format for executables, object code, shared libraries, and core dumps on nearly all Unix-like systems, including Linux.10 The ELF format provides a roadmap that tells the operating system’s kernel how to load and run a program.

An ELF file is composed of several key components:

  • ELF Header: This is the mandatory first section of the file, located at offset zero.11 It begins with a “magic number” (0x7f followed by ELF) that identifies the file as an ELF binary.12 The header also specifies crucial information like the target architecture (e.g., 32-bit or 64-bit), the data encoding (e.g., little-endian or big-endian), the file type (e.g., executable, shared library), and the file offsets pointing to the program and section header tables.13
  • Program Header Table: This table describes the file from an execution perspective. It consists of a series of entries, each defining a segment. A segment is a chunk of the file that the system needs to load into memory to create a running process. For example, one segment will describe the executable code (the .text section), specifying its location in the file, where it should be mapped into virtual memory, and its memory permissions (e.g., read and execute). Another segment will describe the initialized data (the .data section) with its own location and memory permissions (e.g., read and write).14
  • Section Header Table: This table describes the file from a linking perspective. It defines all the sections of the file, which are blocks of data with a specific purpose for tools like the linker and debugger. Common sections include .text (executable instructions), .data (initialized global variables), .bss (uninitialized global variables), .symtab (the symbol table for debugging and static linking), and .strtab (the string table containing symbol names).10

Section II: The POSIX Permission Model: Controlling Access

Section titled “Section II: The POSIX Permission Model: Controlling Access”

The POSIX permission model is the fundamental security mechanism in Linux, governing who can access files and what actions they can perform. It is a simple yet effective system based on three classes of users and three types of permissions. A nuanced understanding of this model, particularly the context-dependent meaning of permissions for files versus directories, is essential for system administration and security.

2.1 The Triad of Control: User, Group, and Other

Section titled “2.1 The Triad of Control: User, Group, and Other”

Every file and directory in a Linux system is associated with one user and one group, which constitute its ownership.1 Access control is then defined for three distinct identity classes:

  • User (u): The owner of the file. The owner has the highest level of control.
  • Group (g): The group that owns the file. This allows permissions to be granted to a collection of users who are members of this group.
  • Other (o): Any user who is not the owner and is not a member of the owning group. This class is sometimes referred to as “world”.15

The symbol a can be used as a shorthand to refer to all three classes (ugo) simultaneously.9

2.2 Permission Semantics: The Dichotomy Between Files and Directories

Section titled “2.2 Permission Semantics: The Dichotomy Between Files and Directories”

The three basic permissions—read (r), write (w), and execute (x)—have distinct and separate meanings depending on whether they are applied to a regular file or a directory. This duality is a frequent source of confusion but is a critical concept for proper system configuration.9

  • On a File: Grants the ability to open the file and read its contents. This permission is necessary to view the data within a file (e.g., using cat) or to make a copy of it.16
  • On a Directory: Grants the ability to list the names of the items (files and subdirectories) contained within that directory. For example, the ls command requires read permission on a directory to display its contents.7 This permission alone does not allow access to the files themselves, only to their names.
  • On a File: Grants the ability to modify, change, or overwrite the contents of the file. This includes truncating the file to zero length or appending new data.16
  • On a Directory: Grants the ability to alter the list of entries within the directory. This is a crucial distinction: write permission on a directory allows a user to create new files, delete existing files, and rename files within that directory.7 The ability to delete a file is therefore governed by the permissions of its parent directory, not the permissions of the file itself.
  • On a File: Grants the ability to execute the file as a program or script. The kernel will attempt to run the file if this bit is set.2
  • On a Directory: Grants the ability to “traverse” or “search” the directory. This permission is required to enter the directory (e.g., with cd) and to access any files or subdirectories within it by name. Even if a user knows the exact name of a file inside a directory and has read permission on that file, they cannot access it without execute permission on the parent directory.2

This leads to a fundamental relationship: the w and x permissions on a directory are interdependent. To modify a directory’s contents (an action governed by the write permission), a process must first be able to access the directory’s data structures. This access is controlled by the execute permission. Consequently, write permission on a directory is ineffective without corresponding execute permission.7 This causal link explains why 755 (rwxr-xr-x) is a standard permission set for directories, while 644 (rw-r--r--) is common for files.

Furthermore, this model reveals that the entity controlling a file’s existence—its name-to-data mapping—is its parent directory. A user could have no permissions whatsoever on a file (chmod 000 file.txt) but still be able to delete it if they possess write and execute permissions on the directory containing it. This non-obvious principle underscores the importance of securing directories to protect the integrity of the files within them.

PermissionEffect on a Regular FileEffect on a Directory
Read rAllows the file’s contents to be read or copied.Allows the names of the files within the directory to be listed.
Write wAllows the file’s contents to be modified or overwritten.Allows files to be created, deleted, or renamed within the directory.
Execute xAllows the file to be run as a program or script.Allows the directory to be entered cd and its contents to be accessed by name.

2.3 Mastering chmod: Symbolic and Octal Notation

Section titled “2.3 Mastering chmod: Symbolic and Octal Notation”

The chmod (change mode) command is the primary tool for modifying file and directory permissions.17 It supports two distinct syntaxes for specifying the desired permission state.

  • Symbolic (Mnemonic) Notation: This method is expressive and ideal for modifying existing permissions. It uses letters to represent the user classes (u, g, o, a), an operator (+ to add, - to remove, or = to set explicitly), and the permission modes (r, w, x).2 For instance, chmod u+x,go-w myfile adds execute permission for the owner aka user while removing write permission for the group and .others. This approach is advantageous for targeted changes, as it does not require knowledge of the file’s current permission state.18
  • Octal (Numeric) Notation: This method is concise and ideal for setting permissions to an absolute, known state. It represents the permissions for each class (user, group, other) with a single octal digit from 0 to 7. This digit is the sum of the values for each permission: read r is 4, write w is 2, and execute x is 1.2 For example, chmod 755 script.sh sets the permissions to rwxr-xr-x. This notation overwrites all existing permissions with the specified state, making it clear and unambiguous for ensuring a specific configuration.19

The choice between notations reflects a difference in intent. Symbolic notation is superior for modifying permissions relative to their current state, whereas octal notation is superior for setting permissions to a defined, absolute state.

2.4 Ownership and Control: The chown Command

Section titled “2.4 Ownership and Control: The chown Command”

Alongside permissions, ownership is a key component of the access control model. The chown (change owner) command is used to modify the user and/or group ownership of a file or directory. Its syntax is straightforward1:

Terminal window
chown <permission> <new_owner>:<new_group filename

Only the superuser (root) can change the ownership of a file to another user.

Section III: Advanced Permissions and File Attributes

Section titled “Section III: Advanced Permissions and File Attributes”

Beyond the basic read, write, and execute model, Linux provides a set of special permission bits that enable critical system functionalities, such as controlled privilege escalation and secure management of shared directories. Additionally, modern extensions like Access Control Lists (ACLs) offer more granular control when the standard POSIX model is insufficient.

3.1 Special Permissions: SUID, SGID, and the Sticky Bit

Section titled “3.1 Special Permissions: SUID, SGID, and the Sticky Bit”

Three special permission bits can be set on files and directories to alter their default behavior. These bits are stored in the same mode field of the inode as the standard permissions.7

  • On an Executable File: The SUID bit is a mechanism for temporary privilege escalation. When an executable file with the SUID bit is run, the resulting process executes with the permissions of the file’s owner, not the user who launched it.7 This is a powerful and potentially dangerous feature. A canonical example is the /usr/bin/passwd utility. It is owned by the root user and has the SUID bit set. This allows a regular user to execute it and, with temporary root privileges, modify the /etc/shadow file to change their own password—an action they could not perform directly.20 Any security vulnerability in a root-owned SUID program, such as a buffer overflow, can be a direct vector for a local attacker to gain full root access to the system, making such binaries a primary target for security audits.21
  • On a Directory: The SUID bit has no effect and is ignored on most Linux and Unix systems.21
  • Setting: chmod u+s filename or chmod 4755 filename.22
  • On an Executable File: Analogous to SUID, an executable with the SGID bit runs with the effective group ID of the file’s group owner.7
  • On a Directory: The SGID bit is a vital tool for collaborative work. When set on a directory, any new files or subdirectories created within it will automatically inherit the group ownership of the parent directory, rather than being owned by the primary group of the creating user. This ensures that all files in a shared project directory retain a consistent group ownership, simplifying access for team members.7
  • Setting: chmod g+s directory or chmod 2775 directory.23
  • On an Executable File: On historical Unix systems, the sticky bit on an executable would hint to the kernel to keep the program’s text segment in swap space after it exited, speeding up subsequent launches. This functionality is obsolete on modern Linux systems.7
  • On a Directory: The sticky bit provides a “restricted deletion” flag, essential for publicly writable directories like /tmp. When the sticky bit is set on a directory, a file within that directory can only be renamed or deleted by the file’s owner, the directory’s owner, or the root user. This prevents users from deleting or tampering with each other’s files in a shared space, even though they all have write permission to the directory itself.7
  • Setting: chmod +t directory or chmod 1777 directory.24
Special BitEffect on an Executable FileEffect on a Directory
SUIDProcess executes with the permissions of the file’s owner.No effect on most Linux/Unix systems.
SGIDProcess executes with the permissions of the file’s group.New files/subdirectories inherit the group ownership of the directory.
Sticky BitObsolete on modern Linux; historically used for performance.Restricted Deletion: Only the file owner, directory owner, or root can delete/rename files within the directory.

3.2 Interpreting s, S, t, and T in Permission Strings

Section titled “3.2 Interpreting s, S, t, and T in Permission Strings”

The ls -l command uses special characters in the execute x position of the permission string to indicate the state of these special bits. The case of the letter is significant and acts as a diagnostic flag.9

  • s (lowercase): Appears in the user’s or group’s permission triplet. It signifies that the SUID or SGID bit is set, respectively, and the underlying execute (x) bit for that class is also set. This is the expected, functional state for a SUID/SGID executable.19
  • S (uppercase): Appears in the user’s or group’s permission triplet. It signifies that the SUID or SGID bit is set, but the underlying execute (x) bit for that class is not set.19 This indicates a likely misconfiguration, as a SUID/SGID permission has no effect on a file that cannot be executed.
  • t (lowercase): Appears in the “other” users’ permission triplet. It signifies that the sticky bit is set and the execute (x) bit for others is also set. This is the normal state for a world-writable shared directory like /tmp.19
  • T (uppercase): Appears in the “other” users’ permission triplet. It signifies that the sticky bit is set, but the execute (x) bit for others is not set.19 This can also be a misconfiguration, as it prevents other users from entering the directory, making the sticky bit’s protection against file deletion by those users moot.
SymbolPositionMeaningIs Execute Bit Set?
sUser or Group xSUID or SGID is set and effective.Yes
SUser or Group xSUID or SGID is set but ineffective.No
tOther xSticky bit is set and effective.Yes
TOther xSticky bit is set but may be ineffective for others.No

3.3 Alternate Access Methods: ACLs and SELinux Contexts

Section titled “3.3 Alternate Access Methods: ACLs and SELinux Contexts”

When the standard ugo permission model is too coarse, Linux provides more advanced mechanisms for access control. The ls -l command indicates their presence with a special character appended to the permission string.

  • Access Control Lists (ACLs): ACLs extend the POSIX model by allowing permissions to be defined for multiple, specific users and groups on a single file. For example, a file can be owned by alice, belong to the editors group, and also grant read-only access specifically to bob and read-write access to the auditors group. The presence of an ACL is indicated by a plus sign (+) at the end of the permission string.25 The getfacl and setfacl commands are used to view and manage ACLs.25
  • SELinux Contexts: On systems using Security-Enhanced Linux (SELinux), such as Red Hat Enterprise Linux and its derivatives, every file and process has a security context (label). Access control decisions are made based on rules in the SELinux policy that govern interactions between these contexts. The presence of an SELinux context is indicated by a dot (.) at the end of the permission string.7 The full context can be viewed with the ls -Z command.26

Section IV: A Taxonomy of Linux File Types

Section titled “Section IV: A Taxonomy of Linux File Types”

The “everything is a file” paradigm in Linux means that the filesystem namespace contains more than just regular files and directories. It also includes special files that serve as interfaces to hardware devices and inter-process communication channels. The type of a file is the most fundamental piece of its metadata, indicated by the first character in the ls -l output.27

4.1 Special Device Files: Block (b) and Character (c)

Section titled “4.1 Special Device Files: Block (b) and Character (c)”

Device files, traditionally located in the /dev directory, are the primary interface between user-space programs and hardware drivers in the kernel.27 Instead of requiring applications to use specialized, hardware-specific APIs, the kernel exposes devices through the standard file API (open, read, write, close). This design greatly simplifies application development and is a core tenet of Unix architecture.28

  • Block Devices (b): These represent devices that read and write data in fixed-size blocks, such as hard drives (/dev/sda), solid-state drives, and USB flash drives. I/O operations on block devices are typically buffered through the kernel’s page cache.27
  • Character Devices (c): These represent devices that handle data as a continuous stream of bytes or characters. Examples include terminals (/dev/tty), serial ports (/dev/ttyS0), and pseudo-devices like /dev/null and /dev/random. I/O for character devices is generally unbuffered.27

Instead of a file size, the ls -l output for a device file displays two numbers separated by a comma: the major and minor device numbers.29

  • Major Number: Identifies the device driver in the kernel that is responsible for managing this type of hardware. For example, all SCSI and SATA disks typically share the same major number.4 The kernel uses this number to route I/O requests to the correct driver code. A list of currently registered major numbers can be found in /proc/devices.30
  • Minor Number: Used by the driver to distinguish between individual physical or logical devices that it controls. For a hard disk driver, the minor number indicates which specific disk and partition is being referenced (e.g., /dev/sda1 will have a different minor number than /dev/sdb2).4

4.2 Inter-Process Communication (IPC) Files: Named Pipes (p) and Sockets (s)

Section titled “4.2 Inter-Process Communication (IPC) Files: Named Pipes (p) and Sockets (s)”

These special files provide persistent endpoints in the filesystem for communication between different processes.

  • Named Pipes (p or FIFO): A named pipe, also called a FIFO (First-In, First-Out), is a file that acts as a unidirectional communication channel. Data written to the pipe by one process can be read by another process in the same order it was written. Unlike the anonymous pipes created for a shell pipeline (e.g., command1 | command2), named pipes have a permanent entry in the filesystem, allowing unrelated processes to communicate by opening the same pipe file.27 They are created with the mkfifo command.31
  • Unix Domain Sockets (s): A socket file provides a bidirectional endpoint for inter-process communication on the same host. It functions much like a network socket but operates entirely within the kernel, bypassing the network stack for significantly higher performance and lower overhead. Sockets are heavily used by local services that need to communicate with clients, such as database servers (e.g., MySQL’s /var/run/mysqld/mysql.sock), X11, and various system daemons.27
SymbolFile TypeDescription
-Regular FileA standard file containing data, such as text, an image, or a binary program.
dDirectoryA special file that contains entries for other files and directories.
lSymbolic LinkA pointer to another file’s pathname.
bBlock DeviceA file representing a block-oriented hardware device (e.g., hard disk).
cCharacter DeviceA file representing a character-stream-oriented device (e.g., terminal).
pNamed Pipe (FIFO)A file for first-in, first-out inter-process communication.
sSocketA file for bidirectional inter-process communication.

Links provide a mechanism for a single file to be referenced by multiple names or from multiple locations in the filesystem hierarchy. The distinction between the two types of links—hard and soft—stems directly from the architectural separation of directory entries and inodes.

A hard link is simply an additional directory entry that points to the exact same inode as an existing file.66 It is not a copy or a pointer; it is another name for the same underlying file data and metadata. All hard links to an inode are peers; there is no concept of an “original” file versus a “linked” file.32

  • Behavior: Because all hard links point to the same inode, any changes to the file’s content or metadata made through one link are immediately visible through all other links.66 Deleting a hard link (e.g., with rm) simply removes one directory entry and decrements the inode’s link count. The file’s data is not marked for deletion until the very last link is removed and the link count drops to zero.33
  • Limitations: The limitations of hard links are a direct consequence of their inode-based implementation.
    1. Cannot cross filesystems: Inode numbers are only unique within a single filesystem. Therefore, a hard link cannot point to an inode on a different partition or device.33
    2. Cannot link to directories: Allowing hard links to directories would create the possibility of cycles in the filesystem tree (e.g., a directory containing a hard link to one of its ancestors), which would break many standard tree-traversal utilities like find and could lead to infinite loops.33

A symbolic link, or symlink, is a special type of file whose data content is simply the text of a pathname to another file or directory.27 It is a pointer to a name, not to an inode.

  • Behavior: When the system accesses a symlink, it reads the pathname stored within it and redirects the access to that target path. If the target file is moved, renamed, or deleted, the symlink is not updated and becomes a “dangling” or “broken” link, pointing to a location that no longer exists.33
  • Advantages: Because they point to pathnames rather than inode numbers, symlinks are free from the limitations of hard links. They can point to directories and can easily cross filesystem boundaries, making them far more flexible and widely used for creating shortcuts and managing complex software installations.34
FeatureHard LinkSoft (Symbolic) Link
Points ToThe file’s inode (metadata and data).The target file’s pathname (a string).
Crosses Filesystems?No. Must be on the same filesystem.Yes. Can point to any path.
Can Link to Directory?No.Yes.
Effect of Deleting OriginalLink remains valid; data persists until all links are gone.Link becomes “dangling” or “broken.”
Inode NumberShares the same inode number as the target.Has its own unique inode number.
Section titled “4.3.3 The Directory Hard Link Count Anomaly Explained”

A newly created, empty directory will always show a hard link count of 2 in the ls -l output.35 This is a standard and predictable behavior rooted in the historical structure of Unix filesystems. The two initial links are:

  1. The directory’s own name entry within its parent directory.
  2. The special . (dot) entry inside the new directory, which is a hard link pointing to the directory itself.

Furthermore, whenever a new subdirectory is created, the link count of its parent directory increases by one. This is because the new subdirectory contains a special .. (dot-dot) entry, which is a hard link pointing back to its parent directory.35 Consequently, the link count for any given directory is always equal to 2 + (number of immediate subdirectories).35

Section V: The Filesystem on Disk: Superblocks, Inodes, and Data Blocks

Section titled “Section V: The Filesystem on Disk: Superblocks, Inodes, and Data Blocks”

To understand how a file path is translated into physical data on a storage device, it is necessary to examine the core on-disk data structures that define a traditional Linux filesystem like ext4. These structures—the superblock, inodes, and data blocks—form a logical hierarchy that organizes the raw storage space of a partition.

5.1 The Superblock: The Filesystem’s Master Blueprint

Section titled “5.1 The Superblock: The Filesystem’s Master Blueprint”

The superblock is the most critical metadata structure for a filesystem. It is typically located at a known offset from the beginning of the partition and contains high-level information about the entire filesystem’s layout and state.36 Its contents serve as a master blueprint, without which the filesystem cannot be mounted or interpreted. Key information stored in the superblock includes:

  • A “magic number” that identifies the filesystem type (e.g., 0xEF53 for ext2/3/4).78
  • The total number of inodes and data blocks in the filesystem.
  • The number of free inodes and data blocks currently available.
  • The size of each data block (e.g., 1024, 2048, or 4096 bytes).
  • The location of the root directory’s inode.
  • Information about the filesystem’s health, such as the last mount time, mount count, and time of the last consistency check (fsck).37

Due to its paramount importance, most filesystems store multiple backup copies of the superblock at different locations across the disk. If the primary superblock becomes corrupted, a filesystem repair utility can use one of these backups to attempt a recovery.38

When a filesystem is created, a specific number of inodes are pre-allocated and stored in one or more inode tables.39 This fixed allocation determines the maximum number of files and directories that the filesystem can ever contain, regardless of the amount of free disk space for data.39 This can lead to a situation where a filesystem reports “No space left on device” not because it is out of data blocks, but because it has exhausted its supply of free inodes. This scenario is common on systems that store a very large number of small files (e.g., mail servers) and can be diagnosed using the df -i command. Each inode is identified by a unique inode number, which serves as its index within the inode table.

5.3 Data Blocks: Where File Content Resides

Section titled “5.3 Data Blocks: Where File Content Resides”

The majority of a partition’s space is allocated to data blocks, which store the actual content of files and the entry lists for directories.40 The connection between a file’s metadata (in its inode) and its content (in data blocks) is made through a series of pointers within the inode itself. This pointer structure is designed as a clever optimization for file access speed, prioritizing the most common use case of small files.

For a typical ext4 inode, the structure is as follows:

  • Direct Pointers: The first set of pointers (e.g., 12 pointers) in the inode point directly to the first data blocks of the file. For small files, this means their entire content can be located by reading only the inode, which is extremely efficient.39
  • Indirect Pointers: If a file is larger than what the direct pointers can address, the inode contains a pointer to an indirect block. This indirect block is not file data; it is a data block filled entirely with more pointers to the file’s data blocks. This requires one extra disk read to access the file’s content.39
  • Double and Triple Indirect Pointers: For very large files, the inode also contains pointers to double indirect and triple indirect blocks, creating a multi-level tree of pointers that can address massive file sizes, albeit with slightly increased latency for accessing distant parts of the file.39

5.4 The Interplay: How a Pathname is Resolved to Data

Section titled “5.4 The Interplay: How a Pathname is Resolved to Data”

The process of accessing a file, such as cat /home/user/report.txt, involves a sequential resolution of the pathname by traversing the filesystem’s structure, using the interplay of these core components.

  1. Start at the Root (/): The process begins at the root directory. The kernel knows the inode number of the root directory (typically inode 2) because it is stored in the superblock.41
  2. Load Root Inode: The kernel reads inode 2 from the inode table into memory. It checks the inode’s metadata to confirm it is a directory and to check for traversal permissions.
  3. Read Root Directory Data: The kernel follows the data block pointers in inode 2 to read the data blocks containing the root directory’s entries. These entries are a list of names and their corresponding inode numbers (e.g., home -> inode 12345, etc -> inode 67890).
  4. Find “home”: The kernel searches this list for the entry named “home” and retrieves its associated inode number.
  5. Traverse to /home: The kernel now repeats the process. It loads the inode for /home, checks that it’s a directory with the necessary permissions, and reads its data blocks to find the entry for “user”.
  6. Traverse to /home/user: This process is repeated again for the “user” directory to find the entry for “report.txt”.
  7. Access the File: The directory entry for “report.txt” provides the final inode number. The kernel loads this inode, performs a final permission check (e.g., does the user have read permission?), and then uses the data block pointers within this final inode to locate and read the actual file content from the disk into memory, which is then delivered to the cat process.

Section VI: From Physical Disk to Virtual Filesystem: Kernel Abstraction

Section titled “Section VI: From Physical Disk to Virtual Filesystem: Kernel Abstraction”

The Linux operating system presents a single, unified filesystem tree to the user, starting from the root directory (/). This clean and consistent view is the result of a sophisticated, multi-layered abstraction model that hides the complexities of the underlying physical storage hardware, partition layouts, and diverse filesystem implementations.

Before a storage device can host a filesystem, it must be partitioned. The partitioning scheme dictates how the map of these divisions—the partition table—is organized on the disk.42

  • Master Boot Record (MBR): The legacy partitioning standard, originating with IBM PC DOS in 1983.43 It resides in the first 512 bytes of the disk.
    • Limitations: MBR suffers from significant limitations that make it unsuitable for modern hardware. It uses 32-bit addressing, restricting it to a maximum disk size of 2 TiB. It also only allows for a maximum of four primary partitions; to create more, one primary partition must be converted into an “extended partition” to act as a container for logical partitions, a cumbersome workaround.42 Furthermore, the MBR stores a single copy of the partition table, making it a single point of failure vulnerable to corruption.44
  • GUID Partition Table (GPT): The modern standard, part of the Unified Extensible Firmware Interface (UEFI) specification, designed to overcome MBR’s limitations.42
    • Advantages: GPT uses 64-bit addressing, supporting disk sizes up to 9.4 ZB (zettabytes). It allows for a large number of partitions (typically 128 by default) without the need for an extended/logical partition structure. For robustness, GPT stores a primary partition table at the beginning of the disk and a backup copy at the end, and it uses CRC32 checksums to verify the integrity of its headers, enabling detection of and recovery from corruption.42 It also includes a “protective MBR” at the start of the disk to prevent legacy, GPT-unaware tools from accidentally misinterpreting and overwriting the disk.42
FeatureMBR (Master Boot Record)GPT (GUID Partition Table)
Maximum Disk Size2 TiB9.4 ZB (Zettabytes)
Partition Limit4 primary (or 3 primary + 1 extended)128 primary partitions (by default)
Data ProtectionSingle partition table (vulnerable)Primary and backup tables with CRC32 checksums
Firmware SupportLegacy BIOSUEFI (and some modern BIOS)
Key LimitationsSmall disk/partition size, limited partitions.Limited support on very old hardware.

6.2 The Virtual File System (VFS): A Universal API

Section titled “6.2 The Virtual File System (VFS): A Universal API”

The Virtual File System (VFS), sometimes called the Virtual Filesystem Switch, is a critical abstraction layer within the Linux kernel that provides a uniform interface for all filesystem operations.28 Its purpose is to allow user-space applications to interact with any filesystem using a single, consistent set of system calls (e.g., open(), read(), write(), close()).45

When an application performs a file operation, the request is handled by the VFS. The VFS then directs the request to the specific driver for the underlying filesystem where the file resides. This driver translates the generic VFS request into the concrete operations required by its on-disk format.46 This architecture is what allows a user to seamlessly copy a file from a local ext4 partition to an XFS RAID array or a remote NFS share without the application needing to know anything about the underlying storage technologies.47 The entire storage stack, from physical disk to user application, can be viewed as a series of these abstraction layers, each hiding the complexity of the one below it.

6.3 A Comparative Analysis of Common Filesystems: ext4, XFS, and Btrfs

Section titled “6.3 A Comparative Analysis of Common Filesystems: ext4, XFS, and Btrfs”

The choice of filesystem is a strategic decision that impacts not only performance but also data integrity and administrative flexibility. While Linux supports dozens of filesystems, three are most prominent in modern deployments.

  • ext4 (Fourth Extended Filesystem): The long-standing default for many Linux distributions, ext4 is the successor to the widely used ext3. It is known for its stability, reliability, and excellent all-around performance. It uses journaling, a technique that logs metadata changes to a dedicated area before they are committed, which dramatically reduces filesystem check times and the risk of corruption after a system crash.48
  • XFS: A high-performance 64-bit journaling filesystem originally developed by Silicon Graphics. XFS is engineered for scalability and excels at handling very large files and filesystems, making it a popular choice for enterprise servers, data warehousing, and media storage. It features efficient metadata handling and support for parallel I/O operations, which optimizes performance on multi-core, multi-disk systems.47
  • Btrfs (B-tree Filesystem): A modern filesystem designed to address the limitations of older systems, with a strong focus on data integrity, fault tolerance, and flexible administration. Its key feature is copy-on-write (CoW), where modifications are written to a new location rather than overwriting existing data. This enables powerful features like efficient, instantaneous snapshots (for backups and rollbacks), built-in data and metadata checksums to detect and protect against silent data corruption (“bit rot”), and integrated volume management that allows for flexible resizing and built-in RAID-like functionality.48

The choice between these filesystems involves trade-offs. While ext4 offers proven stability, Btrfs provides a much higher level of data safety and administrative power, often at the cost of some performance overhead. XFS is optimized for specific high-throughput, large-file workloads.

Featureext4XFSBtrfs
JournalingYes (Metadata)Yes (Metadata)No (Uses Copy-on-Write)
Max Volume Size1 EiB8 EiB16 EiB
Max File Size16 TiB8 EiB16 EiB
SnapshotsNo (via LVM)No (via LVM)Yes (Integrated, CoW-based)
Data IntegrityNo (Metadata only)Yes (Metadata checksums)Yes (Data and metadata checksums)
Integrated RAIDNoNoYes (RAID 0, 1, 10, 5, 6)
Ideal Use CaseGeneral purpose, desktop, application servers.Large file storage, media servers, high-throughput systems.Systems requiring high data integrity, snapshots, and flexible volume management.

Section VII: The Lifecycle of a File: Deletion, Unlinking, and Recovery

Section titled “Section VII: The Lifecycle of a File: Deletion, Unlinking, and Recovery”

Understanding what happens when a file is “deleted” in Linux is fundamental for both system administration and data recovery. The process is not one of immediate erasure but rather of de-referencing, a direct consequence of the separation between directory entries and inodes.

Section titled “7.1 What Happens When You Delete a File: The unlink System Call”

When a user executes the rm filename command, the action performed by the kernel is not “delete,” but “unlink.” The rm command issues the unlink() system call, which performs two specific actions on the filesystem 49:

  1. It removes the directory entry for filename from the list of files in its parent directory.
  2. It decrements the “link count” field stored within the file’s inode.

Crucially, the unlink() call does not touch the inode’s pointers to the data blocks, nor does it erase the data blocks themselves.49 The file’s name is gone, but its metadata and content may still exist on the disk.

The link count in an inode tracks the number of directory entries (hard links) that point to it.5 A file is only considered truly deleted by the filesystem when its link count drops to zero.50 Once the link count reaches zero, the filesystem’s management structures are updated:

  • The inode is marked as free in the filesystem’s inode bitmap.
  • The data blocks associated with the inode are marked as free in the data block bitmap.

At this point, the space previously occupied by the file is now available to be allocated to new files and can be overwritten at any time.51

There is a critical exception to this rule: if a process has a file open when its last link is removed (and its link count drops to zero), the kernel will not free the inode and its data blocks. The file continues to exist, accessible to that process via its file descriptor, even though it has no name in the filesystem. The resources are only released and marked as free after the last process closes its file descriptor for that file.49 This “delete on last close” behavior is a deliberate and powerful design feature. It allows programs to create temporary files that are guaranteed to be cleaned up upon program termination—even if the program crashes—by opening a file and immediately unlinking it.

7.3 Principles of File Recovery: A Race Against Overwriting

Section titled “7.3 Principles of File Recovery: A Race Against Overwriting”

The fact that deletion only marks blocks as available for reuse is the foundation of data recovery. The file’s data often remains intact on the disk until the filesystem allocates those blocks to a new file and overwrites them.52

The Golden Rule of Data Recovery: The single most important action to take after an accidental deletion is to immediately stop all write activity on the affected filesystem. This is best achieved by unmounting the filesystem or remounting it in read-only mode (mount -o remount,ro /dev/device).52 Any new data written to the partition—even from background system processes—could permanently destroy the deleted file’s content.

On modern Solid-State Drives (SSDs), recovery is significantly more challenging. SSDs use the TRIM command to proactively garbage-collect blocks that the filesystem has marked as free. This process, which improves write performance, may involve the drive’s internal controller physically erasing the data blocks long before the operating system attempts to overwrite them, making recovery much less likely.53

7.4 An Overview of Recovery Strategies and Tools

Section titled “7.4 An Overview of Recovery Strategies and Tools”

Several strategies exist for attempting file recovery, with their effectiveness depending on the circumstances of the deletion and the filesystem type.

  • Recovery from /proc: If a file was deleted while a process still had it open, it can often be recovered. The lsof | grep ‘(deleted)’ command can identify such files, and the file’s content can be copied from its entry in the /proc/<pid>/fd/ directory.51
  • Journal-Based Recovery: For journaling filesystems like ext3 and ext4, tools like extundelete can analyze the filesystem journal to find information about recently deleted files and attempt to restore them.52
  • File Carving: Tools like PhotoRec and Foremost work by ignoring the filesystem’s logical structure entirely. They scan the raw block device, looking for known file headers and footers (e.g., the specific byte sequences that mark the beginning of a JPEG or PDF file). This technique, known as file carving, can recover files from corrupted or reformatted partitions but typically loses original filenames and directory structures.52
  • Partition and Filesystem Recovery: TestDisk is a powerful utility designed to recover lost partitions and repair damaged partition tables and boot sectors. It can also undelete files on certain filesystems like FAT and NTFS.54
  • Backup Restoration: The only truly reliable method of data recovery is to restore the lost file from a recent backup. All other methods are best-effort and carry no guarantee of success.52

Section VIII: Filesystem Health and Maintenance: Diagnostics and Repair

Section titled “Section VIII: Filesystem Health and Maintenance: Diagnostics and Repair”

Maintaining the structural integrity of a filesystem is crucial for data reliability and system stability. Filesystem corruption can arise from various sources, including sudden power loss during write operations, hardware failures like bad sectors, software bugs, or administrative errors.55 Linux provides a suite of powerful command-line tools for diagnosing and repairing such issues.

8.1 Identifying Filesystem Errors and Corruption

Section titled “8.1 Identifying Filesystem Errors and Corruption”

The symptoms of filesystem corruption can range from subtle to severe, including the inability to mount a partition, frequent input/output errors when accessing files, or data that appears garbled or is unexpectedly truncated.56

Proactive monitoring is key to preventing catastrophic data loss. The smartmontools package provides the smartctl utility, which can query a drive’s Self-Monitoring, Analysis, and Reporting Technology (S.M.A.R.T.) data to check its overall health and predict potential failures. The badblocks command can perform a non-destructive read-write scan of a disk to identify and mark physically damaged sectors.52

8.2 The fsck Utility: A Front-End for Repair

Section titled “8.2 The fsck Utility: A Front-End for Repair”

The primary tool for checking and repairing Linux filesystems is fsck (File System Consistency Check). It is important to note that fsck itself is not a monolithic program but a front-end wrapper. When invoked, it determines the type of the target filesystem and calls the appropriate backend utility (e.g., e2fsck for ext2/3/4, xfs_repair for XFS).57

The Cardinal Rule: fsck must only be run on an unmounted filesystem. Attempting to repair a mounted filesystem is extremely dangerous and will likely lead to further corruption and data loss.114 This typically requires booting the system into a special rescue mode or using a live USB/CD environment to ensure the target partition is not in use.56

For ext-family filesystems, the check process proceeds through several distinct phases:

  • Phase 1: Checking Inodes, Blocks, and Sizes: Verifies the integrity of each inode and checks for data blocks that are claimed by more than one inode.
  • Phase 2: Checking Directory Structure: Ensures that directory entries are valid and point to existing inodes.
  • Phase 3: Checking Directory Connectivity: Traverses the filesystem tree to find any “orphaned” inodes—inodes that are marked as in-use but are not referenced by any directory entry.
  • Phase 4: Checking Reference Counts: Verifies that the hard link count in each inode matches the actual number of directory entries pointing to it.
  • Phase 5: Checking Group Summary Information: Validates the filesystem’s bitmaps, which track free and allocated inodes and data blocks, ensuring they are consistent with the findings of the previous phases.55

If fsck finds orphaned files or directories, it will reconnect them to the lost+found directory located at the root of the filesystem. The reconnected files will be named after their inode number.55 It is crucial to recognize that the primary goal of these repair tools is to restore metadata consistency to make the filesystem structurally sound and mountable. This can sometimes come at the cost of data integrity. A repair process may truncate a corrupted file or discard unrecoverable data blocks to achieve a consistent state. This underscores the importance of creating a block-level image of a damaged partition with a tool like ddrescue before attempting any repairs.

8.3 Low-Level Debugging with debugfs (for ext2/3/4)

Section titled “8.3 Low-Level Debugging with debugfs (for ext2/3/4)”

For ext-family filesystems, debugfs provides an interactive, low-level debugger that allows for direct examination and manipulation of internal filesystem structures.58 It is an expert tool that can be used for advanced recovery and analysis.

Common debugfs operations include:

  • Listing recently deleted inodes (lsdel).
  • Viewing the full contents of an inode (stat <inode_number>).
  • Dumping the contents of a file given its inode number (dump <inode_number> output_file).
  • Manually modifying an inode’s fields, such as setting its deletion time to zero to attempt an undelete (mi <inode_number>).58

Warning: Using debugfs in write mode (-w) is extremely hazardous. An incorrect command can irrevocably destroy the filesystem. It should only be used as a last resort, preferably on an image of the disk rather than the live device.59

8.4 Repairing XFS Filesystems with xfs_repair

Section titled “8.4 Repairing XFS Filesystems with xfs_repair”

For the XFS filesystem, the dedicated repair utility is xfs_repair.60 Like fsck, it must be run on an unmounted filesystem. A non-destructive check can be performed using the -n option, which will report on the filesystem’s health without making any changes.

A unique feature of XFS is its journal, which must be clean before a repair can proceed. If the filesystem was not unmounted cleanly, xfs_repair may refuse to run, instructing the user to first mount and unmount the filesystem to allow the log to be replayed. In cases of severe corruption where the log itself is damaged, the -L option can be used to zero the log. This is a dangerous, last-resort option that can lead to data loss, as it discards any metadata changes that were in the process of being committed.61

Section IX: Command-Line Mastery: Practical Filesystem Interaction

Section titled “Section IX: Command-Line Mastery: Practical Filesystem Interaction”

A theoretical understanding of the filesystem must be paired with proficiency in the command-line tools used to interact with it. This section focuses on the practical application and nuances of key commands, directly addressing the user’s specific queries.

9.1 Advanced ls Usage: A Deep Dive into Common Flags

Section titled “9.1 Advanced ls Usage: A Deep Dive into Common Flags”

The ls command is the primary tool for listing directory contents, but its true power lies in its numerous options that control sorting, formatting, and the level of detail displayed.

OptionDescriptionExample Usage
-aLists all files, including hidden files and directories that start with a dot (.).ls -a /home/user
-tSorts the output by modification time, with the newest entries listed first.ls -lt
-rReverses the current sort order.ls -r
-trA common combination that sorts by modification time, but in reverse, listing the oldest entries first.ls -ltr
-FAppends a character to each entry to classify its type: / for directories, * for executables, @ for symbolic links, etc.ls -F
-RLists the contents of all subdirectories Recursively, traversing the entire directory tree.ls -R /etc
-hWhen used with -l, displays file sizes in a human-readable format (e.g., 4.0K, 1.2M, 2.5G).ls -lh

9.2 Recursive chmod and the Perils of chmod -R a-x

Section titled “9.2 Recursive chmod and the Perils of chmod -R a-x”

A common administrative task is to change permissions recursively throughout a directory tree. While chmod -R is the tool for this, its indiscriminate application can have disastrous consequences, particularly when modifying the execute bit. The user query specifically asks why a command like chmod -R a-x mydir is problematic.

The issue stems from the dual meaning of the execute (x) permission. For a file, x means it can be run as a program. For a directory, x means it can be traversed or entered. Removing the execute permission from a directory makes it inaccessible; no user (except root) can cd into it or access any of the files or subdirectories it contains, even if they have read and write permissions on the directory.9

Therefore, running chmod -R a-x on a directory tree will remove the execute permission from all files and all subdirectories. While this may be the desired outcome for the files, it renders every subdirectory within the tree unusable, effectively locking users out of the directory structure.

9.3 The Correct Approach: Combining find with chmod for Granular Control

Section titled “9.3 The Correct Approach: Combining find with chmod for Granular Control”

The correct method for recursively managing permissions, especially the execute bit, is to treat files and directories separately. The find command is the ideal tool for this, as it can select items based on their type (-type f for files, -type d for directories) and then execute a command on them.62

This approach is not merely a “trick” but a fundamental pattern for correct permission management, necessitated by the different semantics of the x permission bit. Because a blanket command like chmod -R cannot distinguish between file types, a more intelligent tool like find is required.

  • To properly set permissions for a web server directory (a common use case):
    • Set all directories to 755 (rwxr-xr-x) to allow traversal: find /var/www/html \-type d -exec chmod 755 {} \\;
    • Set all files to 644 (rw-r—r—), as web assets typically do not need to be executable: find /var/www/html \-type f \-exec chmod 644 {} \\; 62
  • To solve the user’s specific problem of removing the execute permission from files only:
    • The correct command is: find mydir -type f -exec chmod a-x {} \\;
    • This command precisely targets only items of type f (file) and executes chmod a-x on them, leaving the essential execute permission on all directories (-type d) intact.63

The Linux filesystem, while intricate, is built upon a set of consistent and logical principles. Its architecture is a masterclass in abstraction, layering concepts from physical disk partitions (MBR/GPT) and on-disk data structures (superblocks, inodes, data blocks) to the universal interface of the Virtual File System. This layered model provides the immense flexibility and power that allows Linux to seamlessly manage a vast array of storage devices and filesystem types under a single, coherent directory tree.

A deep understanding of this system hinges on several key concepts. First is the fundamental separation of a file’s name, which is merely a reference in a directory, from its inode, which holds all metadata and pointers to the actual data. This distinction is the linchpin that explains the behavior of hard links, the mechanics of file deletion via the unlink system call, and the principles of data recovery.

Second is the nuanced POSIX permission model. The context-dependent meaning of read, write, and execute permissions for files versus directories is critical for both security and functionality. The execute permission on a directory, which grants the ability to traverse it, is a particularly vital concept, and its misunderstanding is the source of common administrative errors, such as the improper use of chmod -R. The special permissions—SUID, SGID, and the sticky bit—provide essential mechanisms for controlled privilege escalation and secure collaboration, but they must be managed with care due to their security implications.

Finally, proficiency with command-line tools like ls, chmod, find, and fsck is the practical application of this theoretical knowledge. Mastering these utilities allows a developer or system administrator to not only manage the filesystem but also to diagnose complex issues, repair corruption, and build robust, system-aware tools. By grasping these foundational principles—from the bits in an inode to the layers of kernel abstraction—one gains the necessary insight to effectively debug and engineer solutions on any Linux-based system.

  1. Classic SysAdmin: Understanding Linux File Permissions - Linux Foundation, accessed August 24, 2025, https://www.linuxfoundation.org/blog/blog/classic-sysadmin-understanding-linux-file-permissions 2 3 4 5 6 7

  2. Linux Permissions Explained - phoenixNAP, accessed August 24, 2025, https://phoenixnap.com/kb/linux-file-permissions 2 3 4 5

  3. Linux Command Line Interface (CLI) — Part 9: Linux file system, Directory Structure & File Metadata | by Bharath | Aug, 2025 | Medium, accessed August 24, 2025, https://medium.com/@bharath/linux-command-line-interface-cli-part-9-linux-file-system-directory-structure-file-metadata-b607c68e135f 2 3

  4. Major and Minor Numbers | The Linux Tutorial, accessed August 24, 2025, http://www.linux-tutorial.info/?page_id=253 2 3

  5. What is metadata, and how does it aid in the “fsck” process? - Unix & Linux Stack Exchange, accessed August 24, 2025, https://unix.stackexchange.com/questions/23252/what-is-metadata-and-how-does-it-aid-in-the-fsck-process 2

  6. What Is Metadata and How Does It Aid in the fsck Process? | Baeldung on Linux, accessed August 24, 2025, https://www.baeldung.com/linux/metadata-fsck-process

  7. File-system permissions - Wikipedia, accessed August 24, 2025, https://en.wikipedia.org/wiki/File-system_permissions 2 3 4 5 6 7 8 9 10 11 12 13 14

  8. Understanding UNIX permissions and file types, accessed August 24, 2025, https://unix.stackexchange.com/questions/183994/understanding-unix-permissions-and-file-types

  9. File permissions and attributes - ArchWiki, accessed August 24, 2025, https://wiki.archlinux.org/title/File_permissions_and_attributes 2 3 4 5

  10. Executable and Linkable Format - Wikipedia, accessed August 24, 2025, https://en.wikipedia.org/wiki/Executable_and_Linkable_Format 2

  11. elf(5) - Linux manual page - man7.org, accessed August 24, 2025, https://man7.org/linux/man-pages/man5/elf.5.html

  12. The 101 of ELF files on Linux: Understanding and Analysis - Linux …, accessed August 24, 2025, https://linux-audit.com/elf-binaries-on-linux-understanding-and-analysis/

  13. What Is an ELF File? | Baeldung on Linux, accessed August 24, 2025, https://www.baeldung.com/linux/executable-and-linkable-format-file

  14. Understanding the Basics of ELF Files on Linux - DEV Community, accessed August 24, 2025, https://dev.to/bytehackr/understanding-the-basics-of-elf-files-on-linux-61c

  15. Deciphering Linux File System Permissions - Presslabs, accessed August 24, 2025, https://www.presslabs.com/code/linux-file-system-permissions/

  16. Linux file permissions explained - Red Hat, accessed August 24, 2025, https://www.redhat.com/en/blog/linux-file-permissions-explained 2

  17. Linux Basics: Level 2— Exploring the Linux File System and Permissions - Medium, accessed August 24, 2025, https://medium.com/@jeromedecinco/linux-basics-level-2-exploring-the-linux-file-system-and-permissions-d8780cada4fd

  18. Understanding chmod Symbolic Notation and use of Octal - Ask Ubuntu, accessed August 24, 2025, https://askubuntu.com/questions/518259/understanding-chmod-symbolic-notation-and-use-of-octal

  19. Changing File Permissions, accessed August 24, 2025, https://docs.oracle.com/cd/E19504-01/802-5750/6i9g464pv/index.html

  20. Linux File Permissions: Understanding setuid, setgid, and the Sticky …, accessed August 24, 2025, https://www.cbtnuggets.com/blog/technology/system-admin/linux-file-permissions-understanding-setuid-setgid-and-the-sticky-bit

  21. setuid - Wikipedia, accessed August 24, 2025, https://en.wikipedia.org/wiki/Setuid 2

  22. Understanding setuid, setgid, and the Sticky Bit in Linux | by Himanshu Raj | Medium, accessed August 24, 2025, https://medium.com/@rajhimanshu203/understanding-setuid-setgid-and-the-sticky-bit-in-linux-080d6954d8ea

  23. Advance File Permissions in Linux - GeeksforGeeks, accessed August 24, 2025, https://www.geeksforgeeks.org/linux-unix/advance-file-permissions-in-linux/

  24. Special Permissions (Setuid, Setgid, Sticky Bit) -, accessed August 24, 2025, https://nishantmunjal.com/lesson/special-permissions-setuid-setgid-sticky-bit/

  25. Plus sign in ls output - Linux Audit, accessed August 24, 2025, https://linux-audit.com/plus-sign-ls-output/ 2

  26. What does the dot mean at the end of `-rw-r—r—`? How do you set it with `chmod`?, accessed August 24, 2025, https://superuser.com/questions/230559/what-does-the-dot-mean-at-the-end-of-rw-r-r-how-do-you-set-it-with-chmod

  27. File types In Linux/Unix explained in detail. - Linux.com, accessed August 24, 2025, https://www.linux.com/training-tutorials/file-types-linuxunix-explained-detail/ 2 3 4 5 6 7

  28. Virtual File Systems - IBM, accessed August 24, 2025, https://www.ibm.com/docs/en/aix/7.2.0?topic=concepts-virtual-file-systems 2

  29. Device Major and Minor Numbers - The Linux Documentation Project, accessed August 24, 2025, https://tldp.org/HOWTO/Partition-Mass-Storage-Definitions-Naming-HOWTO/x183.html

  30. Device nodes and major/minor numbers for devices in Linux on IBM …, accessed August 24, 2025, https://www.ibm.com/docs/en/linux-on-systems?topic=hdaa-device-nodes-numbers

  31. Exploring Named Pipes in Linux. Introduction | by Murad Bayoun - Medium, accessed August 24, 2025, https://medium.com/@bayounm95.eng/exploring-named-pipes-in-linux-f430cd303475

  32. Deleting files and Inodes - unix - Stack Overflow, accessed August 24, 2025, https://stackoverflow.com/questions/8860720/deleting-files-and-inodes

  33. What is the difference between a symbolic link and a hard link? - Stack Overflow, accessed August 24, 2025, https://stackoverflow.com/questions/185899/what-is-the-difference-between-a-symbolic-link-and-a-hard-link 2 3 4

  34. Explaining Soft Link And Hard Link In Linux With Examples …, accessed August 24, 2025, https://ostechnix.com/explaining-soft-link-and-hard-link-in-linux-with-examples/

  35. ls - Why does a new directory have a hard link count of 2 before …, accessed August 24, 2025, https://unix.stackexchange.com/questions/101515/why-does-a-new-directory-have-a-hard-link-count-of-2-before-anything-is-added-to 2 3

  36. File system drivers (Part 1) — The Linux Kernel documentation, accessed August 24, 2025, https://linux-kernel-labs.github.io/refs/pull/189/merge/labs/filesystems_part1.html

  37. 3. Global Structures — The Linux Kernel documentation, accessed August 24, 2025, https://www.kernel.org/doc/html/v5.5/filesystems/ext4/globals.html

  38. What is a Superblock, Inode, Dentry and a File? - Unix & Linux Stack Exchange, accessed August 24, 2025, https://unix.stackexchange.com/questions/4402/what-is-a-superblock-inode-dentry-and-a-file

  39. Inode in Operating System - GeeksforGeeks, accessed August 24, 2025, https://www.geeksforgeeks.org/operating-systems/inode-in-operating-system/ 2 3 4 5

  40. The Second Extended File System - Unix/Linux Systems Programming, accessed August 24, 2025, https://cscie28.dce.harvard.edu/lectures/lect04/6_Extras/ext2-struct.html

  41. What Is Superblock, Inode, Dentry and File in Linux? | Baeldung on …, accessed August 24, 2025, https://www.baeldung.com/linux/superblock-inode-dentry-file

  42. Partitioning - ArchWiki, accessed August 24, 2025, https://wiki.archlinux.org/title/Partitioning 2 3 4 5

  43. MBR vs GPT: Understanding the Key Differences in Partitioning - SynchroNet, accessed August 24, 2025, https://synchronet.net/mbr-vs-gpt/

  44. MBR vs GPT: Understanding Disk Partitioning Schemes - Codefinity, accessed August 24, 2025, https://codefinity.com/blog/MBR-vs-GPT%3A-Understanding-Disk-Partitioning-Schemes

  45. Chapter 15: File System Internals, accessed August 24, 2025, https://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci340/slides/chapter15.pdf

  46. Linux Storage: Filesystems Introduction - MyBlueLinux.com, accessed August 24, 2025, https://www.mybluelinux.com/linux-storage-filesystems-introduction/

  47. Linux File System - GeeksforGeeks, accessed August 24, 2025, https://www.geeksforgeeks.org/linux-unix/linux-file-system/ 2

  48. Exploring the Dynamic World of Linux Filesystems: Ext4, XFS, and Btrfs, accessed August 24, 2025, https://www.linuxjournal.com/content/exploring-dynamic-world-linux-filesystems-ext4-xfs-and-btrfs 2

  49. unlink(2) - Linux manual page - man7.org, accessed August 24, 2025, https://man7.org/linux/man-pages/man2/unlink.2.html 2 3

  50. A file opened for read and write can be unlinked - Stack Overflow, accessed August 24, 2025, https://stackoverflow.com/questions/19441823/a-file-opened-for-read-and-write-can-be-unlinked

  51. Can a file be retrieved by its inode? - Unix & Linux Stack Exchange, accessed August 24, 2025, https://unix.stackexchange.com/questions/92816/can-a-file-be-retrieved-by-its-inode 2

  52. Linux Data Recovery: How to Salvage Lost or Corrupted Files …, accessed August 24, 2025, https://www.linuxjournal.com/content/linux-data-recovery-how-salvage-lost-or-corrupted-files 2 3 4 5 6

  53. Recovering deleted files using only grep - Hacker News, accessed August 24, 2025, https://news.ycombinator.com/item?id=7943981

  54. How to recover deleted files? - Ask Ubuntu, accessed August 24, 2025, https://askubuntu.com/questions/3883/how-to-recover-deleted-files

  55. FSCK explained · Site Reliability Engineer HandBook, accessed August 24, 2025, https://s905060.gitbooks.io/site-reliability-engineer-handbook/content/fsck_explained.html 2 3

  56. How to Use ‘fsck’ to Repair File System Errors in Linux - Tecmint, accessed August 24, 2025, https://www.tecmint.com/fsck-repair-file-system-errors-in-linux/ 2

  57. fsck(8) - Linux manual page - man7.org, accessed August 24, 2025, https://man7.org/linux/man-pages/man8/fsck.8.html

  58. debugfs Command Examples, accessed August 24, 2025, https://www.cs.montana.edu/courses/309/topics/4-disks/debugfs_example.html 2

  59. debugfs(8) - Linux manual page - man7.org, accessed August 24, 2025, https://man7.org/linux/man-pages/man8/debugfs.8.html

  60. Running repairs on XFS Filesystems - Ucartz, accessed August 24, 2025, https://www.ucartz.com/clients/knowledgebase/1264/Running-repairs-on-XFS-Filesystems.html

  61. How to fix a corrupt XFS file system - Teradata Support, accessed August 24, 2025, https://support.teradata.com/knowledge?id=kb_article_view&sys_kb_id=1cab62de1bbaf1180d90a9b5624bcbc0

  62. How do I change permissions for a folder and its subfolders/files? [closed] - Stack Overflow, accessed August 24, 2025, https://stackoverflow.com/questions/3740152/how-do-i-change-permissions-for-a-folder-and-its-subfolders-files 2

  63. command line - How to remove execute permission from all txt files …, accessed August 24, 2025, https://askubuntu.com/questions/828531/how-to-remove-execute-permission-from-all-txt-files-in-ubuntu