File Systems and Mounting
Virtual File System (VFS) Layer
Section titled “Virtual File System (VFS) Layer”The Virtual File System layer is the kernel abstraction that allows Linux to support multiple file System types simultaneously. Application code calls open(2)``read(2)``write(2)And stat(2) Without knowing whether the underlying storage uses ext4, XFS, Btrfs, NFS, or a pseudo-filesystem Like procfs.
graph TD
A[User Space Applications] -->|open, read, write| B[System Call Interface]
B --> C[VFS Layer]
C --> D[ext4]
C --> E[XFS]
C --> F[Btrfs]
C --> G[NFS / CIFS]
C --> H[tmpfs / procfs / sysfs]
C --> I[FUSE]
D --> J[Block Device Layer]
E --> J
F --> J
G --> K[Network Stack]
H --> L[Memory / Kernel]
I --> M[User-Space Daemon]
J --> N[Physical Storage]VFS Objects
Section titled “VFS Objects”The VFS maintains four primary object types:
| Object | Description | Kernel Type |
|---|---|---|
| superblock | Describes a mounted file system (type, size, flags) | struct super_block |
| inode | Represents a single file (metadata: permissions, size, timestamps) | struct inode |
| dentry | Directory entry — maps a name to an inode | struct dentry |
| file | Represents an open file (current offset, access mode) | struct file |
The dentry cache (dcache) holds the directory hierarchy in memory, avoiding disk lookups for Frequently accessed paths. The inode cache (icache) keeps recently accessed inodes in memory. Both Caches are critical for performance — a warm dentry cache means stat(2) on a file requires no disk I/O.
File System Registration
Section titled “File System Registration”Each file system type registers with the VFS using register_filesystem(). The registration Includes a struct file_system_type that provides:
- Name (e.g., “ext4”, “xfs”, “btrfs”)
- Mount function pointer
- Kill superblock function pointer
- Module owner (for loadable modules)
When mount(2) is called, the VFS invokes the appropriate file system”s mount function, which reads The superblock from disk and populates the VFS superblock object.
Inode Structure
Section titled “Inode Structure”An inode (index node) is the fundamental data structure representing a file on disk. It contains all Metadata about a file except the filename (which is stored in the directory’s data blocks, not in The inode itself).
Inode Fields
Section titled “Inode Fields”| Field | Description |
|---|---|
st_mode | File type and permissions (16 bits) |
st_ino | Inode number (unique within file system) |
st_dev | Device number (identifies the file system) |
st_nlink | Hard link count |
st_uid | Owner user ID |
st_gid | Owner group ID |
st_size | File size in bytes (for regular files) |
st_blksize | Preferred block size for I/O |
st_blocks | Number of 512-byte blocks allocated |
st_atim | Last access time (can be disabled with noatime) |
st_mtim | Last modification time (data change) |
st_ctim | Last status change time (metadata change) |
Hard Links and the Inode
Section titled “Hard Links and the Inode”A hard link is an additional directory entry pointing to the same inode. The inode’s link Count (st_nlink) tracks how many directory entries reference it. When the link count reaches zero And no process has the file open, the inode and its data blocks are freed.
# Demonstrate hard linksecho "content" > file1.txtln file1.txt file2.txt # hard linkln -s file1.txt file3.txt # symbolic link
stat file1.txt# Inode: 123456 Links: 2
stat file2.txt# Inode: 123456 Links: 2 (same inode)
stat file3.txt# Inode: 789012 Links: 1 (different inode — symlink)File Types
Section titled “File Types”The file type is encoded in the upper bits of st_mode:
| Octal | Type | Description |
|---|---|---|
| 010000 | Regular file | Normal data file |
| 004000 | Directory | Contains directory entries |
| 012000 | Symbolic link | Pointer to another file |
| 001000 | FIFO (named pipe) | Inter-process communication |
| 006000 | Block device | Buffered access (e.g., /dev/sda) |
| 002000 | Character device | Unbuffered access (e.g., /dev/null) |
| 014000 | Socket | Network communication endpoint |
# Test file types[ -f file ] # regular file[ -d dir ] # directory[ -L link ] # symbolic link[ -p pipe ] # named pipe[ -b dev ] # block device[ -c dev ] # character device[ -S socket ] # socket
# Using statstat -c '%F' /dev/null # "character special file"stat -c '%F' /dev/sda # "block special file"Ext4 is the default file system on most Linux distributions. It is the evolutionary successor to Ext2 and ext3, adding extents, larger volumes, journal checksumming, and delayed allocation.
Key Features
Section titled “Key Features”| Feature | ext4 Details |
|---|---|
| Max volume size | 1 EiB (2^64 bytes theoretical, 64 TiB practical) |
| Max file size | 16 TiB |
| Max files | ~4 billion |
| Block sizes | 1024, 2048, 4096 bytes |
| Journaling | Ordered mode (default), writeback, journal |
| Allocation | Extents (replaces indirect block mapping) |
| Checksums | Journal checksums, metadata checksums (metadata_csum) |
| Timestamps | nanosecond granularity |
Extents
Section titled “Extents”Traditional ext2/ext3 used indirect block mapping — the inode pointed to a block of pointers, which Could point to more pointer blocks (up to 3 levels of indirection). This was inefficient for large Files because even a contiguous file required multiple block pointer lookups.
Ext4 introduces extents — a descriptor that maps a contiguous range of blocks. An extent can Describe up to 128 MiB of contiguous data in a single descriptor. For most files, the extent tree Fits entirely within the inode (no separate extent block needed).
Extent descriptor: [logical_block, physical_block, length] [0, 1000, 100] → blocks 0-99 mapped to disk blocks 1000-1099Journaling
Section titled “Journaling”Ext4 uses a journal to ensure file system consistency after a crash. The journal records metadata Changes (and optionally data changes) before committing them to the main file system.
| Journal Mode | What is Journaled | Performance | Safety |
|---|---|---|---|
ordered (default) | Metadata only (data written before metadata committed) | Good | High |
writeback | Metadata only (no ordering guarantee) | Best | Medium |
journal | Both metadata and data | Slowest | Highest |
# View current journal modetune2fs -l /dev/sda1 | grep "Default mount options"
# Set journal mode (in /etc/fstab or tune2fs)mount -o data=journal /dev/sda1 /mntDelayed Allocation
Section titled “Delayed Allocation”Ext4 uses delayed allocation (delalloc): when a process writes data, the blocks are not Immediately allocated on disk. Instead, the data is held in memory, and allocation is deferred until The kernel flushes it. This allows the allocator to make better decisions about contiguous block Placement, significantly reducing fragmentation.
The downside: a crash before flush can lose more data than with immediate allocation. For databases That manage their own I/O (MySQL, PostgreSQL), delayed allocation should be disabled:
# Disable delayed allocation for database volumesmount -o nodelalloc /dev/sdb1 /var/lib/mysql# or in /etc/fstab:# /dev/sdb1 /var/lib/mysql ext4 defaults,nodelalloc 0 2ext4 Tuning
Section titled “ext4 Tuning”# Reserve blocks for root (default 5%)tune2fs -m 1 /dev/sda1 # reduce to 1%
# Enable directory indexingtune2fs -O dir_index /dev/sda1
# Enable large file supporttune2fs -O large_file /dev/sda1
# Enable 64-bit mode (required for volumes > 16 TiB)tune2fs -O 64bit /dev/sda1
# Check file system (must be unmounted or read-only)e2fsck -f /dev/sda1
# View file system parameterstune2fs -l /dev/sda1dumpe2fs /dev/sda1
# Resize ext4 (can be done online for grow, offline for shrink)resize2fs /dev/sda1 500G # grow to 500 GiBXFS is a high-performance journaling file system developed by SGI in 1993, designed for parallel I/O And large files. It is the default on RHEL/CentOS 7+ and is well-suited for large data volumes, Media workloads, and databases.
Key Features
Section titled “Key Features”| Feature | XFS Details |
|---|---|
| Max volume size | 16 EiB (8 EiB on 32-bit systems) |
| Max file size | 8 EiB |
| Max files | Practically unlimited (based on space) |
| Block sizes | 512 to 65536 bytes (must be a power of 2, page-aligned) |
| Journaling | Metadata-only journal (separate log device supported) |
| Allocation | B+tree-based extent allocation |
| Allocation Groups | Independent regions for parallel allocation |
Allocation Groups
Section titled “Allocation Groups”An XFS file system is divided into Allocation Groups (AGs), each of which manages its own free Space and inodes independently. This design enables parallel I/O — multiple processes can allocate Blocks in different AGs simultaneously without lock contention.
# View allocation group informationxfs_info /dev/sdb1# agcount=4, agsize=... (4 allocation groups)
# AG count is automatically calculated based on volume size:# Volume < 1 GiB: 1 AG# Volume < 4 GiB: 4 AGs# Volume < 16 GiB: 8 AGs# Volume < 64 GiB: 16 AGs# Volume < 256 GiB: 32 AGs# etc.B+tree Structures
Section titled “B+tree Structures”XFS uses B+trees extensively for its internal data structures:
- Inode B+tree: Maps inode numbers to inode locations within AGs
- Free space B+tree: Tracks free extents within each AG (by block number and by extent length)
- Extent B+tree: Maps file offsets to disk extents (for files with more than 4 extents)
B+trees are preferred over B-trees because all data is stored in leaf nodes, and internal nodes Contain only keys. This means each internal node can hold more keys, reducing tree depth and the Number of disk seeks required for lookups.
XFS vs ext4
Section titled “XFS vs ext4”| Aspect | ext4 | XFS |
|---|---|---|
| Volume resize | Can grow online, shrink offline | Can grow online, cannot shrink |
| Metadata repair | e2fsck (can be slow) | xfs_repair (fast but requires free space) |
| Delete performance | Good | Excellent (delayed allocation of AGs) |
| Large files | Good | Excellent (designed for large files) |
| Small files | Better | Good (more metadata overhead) |
| Fragmentation | More susceptible | Less (extents + AGs) |
| Snapshots | No native support | No native support (use LVM/Btrfs) |
XFS Tuning
Section titled “XFS Tuning”# Create XFS with specific optionsmkfs.xfs -f -b size=4096 -d agcount=8 -l size=512m /dev/sdb1
# View XFS parametersxfs_info /mount/point
# Grow XFS (online, no shrink possible)xfs_growfs /mount/point
# Repair XFS (must be unmounted)xfs_repair /dev/sdb1
# Freeze/thaw file system (for consistent snapshots)xfs_freeze -f /mount/point# ... take snapshot ...xfs_freeze -u /mount/point
# Defragment a filexfs_fsr /mount/point/path/to/file