Linux Disk Partitions and File Systems: Complete Admin Guide

Disk partitions and file systems are the foundation of every Linux installation. Before any data can be stored, the disk must be divided (partitioned) and each partition must be formatted with a file system. Understanding this deeply — from the MBR structure to inode internals — is essential for the RHCA exam and for troubleshooting real production systems.

Why Partition a Disk?

Partitioning divides a single physical disk into multiple independent logical units. Each partition behaves as a separate disk from the operating system's perspective. The reasons for partitioning are:

  • Fault isolation: A corrupted or full file system affects only its own partition. If /var fills up due to runaway log files, it does not affect / (root), which could otherwise bring down the entire system.
  • Performance tuning: Different partitions can use different block sizes or file system types optimised for their specific workload. A database partition might use XFS with a large block size, while a partition holding small configuration files might use ext4 with a smaller block size.
  • Disk quota enforcement: Linux disk quotas operate at the partition level. You cannot limit user disk usage across multiple mount points without separate partitions.
  • Security: You can mount specific partitions with restrictive options like noexec (prevent running executables), nosuid (ignore SUID/SGID bits), or nodev (ignore device files). This is standard hardening for /tmp and /var.
  • Dual-boot support: Multiple operating systems on the same disk each need their own partition.

Disk Naming Conventions in Linux

Linux identifies disk devices through the kernel's device driver. The naming follows a predictable pattern based on the disk controller type:

InterfaceDevice NamesPartition NamesNotes
IDE / PATA/dev/hda, /dev/hdb/dev/hda1, /dev/hda2Older interface, rarely used today
SCSI / SATA / SAS/dev/sda, /dev/sdb/dev/sda1, /dev/sda2Most common in physical servers
NVMe SSD/dev/nvme0n1/dev/nvme0n1p1High-performance SSDs
Virtual (KVM)/dev/vda, /dev/vdb/dev/vda1, /dev/vda2Para-virtualised disks
iSCSI/LUN/dev/sdb, /dev/sdc/dev/sdb1Network-attached block storage

Abbreviations: IDE = Integrated Drive Electronics, SCSI = Small Computer System Interface, iSCSI = Internet SCSI, SAS = Serial Attached SCSI, SATA = Serial ATA

MBR vs GPT — Disk Partition Tables

The partition table is stored at the very beginning of the disk and tells the OS how the disk is divided.

MBR (Master Boot Record)

MBR occupies the first 512 bytes of the disk (sector 0). Its structure is fixed:

OffsetSizeNamePurpose
0446 bytesIPL (Initial Program Loader)Contains the secondary bootloader (GRUB stage 1). This code is executed by BIOS to initiate OS boot.
44664 bytesPTI (Partition Table Information)Contains 4 partition entries of 16 bytes each — partition type, start/end sectors, size
5102 bytesMagic number / ValidationMust be 0x55 0xAA for BIOS to recognise it as valid. If missing, BIOS refuses to boot.

MBR Limitations:

  • Maximum 4 primary partitions per disk
  • Maximum disk size: 2 TB (32-bit sector addressing × 512 bytes)
  • Only 3 primary + 1 extended partition (extended can hold unlimited logical partitions)

GPT (GUID Partition Table)

GPT is the modern replacement for MBR. Key advantages:

  • Supports up to 128 partitions by default (no extended/logical distinction)
  • Maximum disk size: 9.4 ZB (zetabytes — essentially unlimited)
  • Stores a backup partition table at the end of the disk (redundancy)
  • Each partition has a unique GUID (Globally Unique Identifier)
  • Required for UEFI boot systems
# Check if disk uses MBR or GPT:
# parted /dev/sda print | grep "Partition Table"
# gdisk -l /dev/sda                 # GPT-aware tool
# parted /dev/sda mklabel gpt       # convert to GPT (DESTRUCTIVE)
# parted /dev/sda mklabel msdos     # convert to MBR (DESTRUCTIVE)

MBR Partition Types

With MBR, there are three types of partitions:

  • Primary Partition: Directly listed in the MBR partition table. Maximum 4 per disk. Can be made bootable. The OS is installed on a primary partition.
  • Extended Partition: A special primary partition that acts as a container. There can be only one extended partition per MBR disk. It is NOT directly usable — it just holds logical partitions.
  • Logical Partition: Created inside the extended partition. Numbered from 5 onwards (sda5, sda6…) regardless of how many primaries exist. There is no practical limit on the number of logical partitions.

Practical rule: Most Linux systems use 3 primary partitions (/boot, swap, /) and one extended partition containing logical partitions for additional storage.

Creating Partitions with fdisk

fdisk is the standard tool for MBR partitioning. All changes are made in memory and only written to disk when you type w.

# List all disks and existing partitions:
# fdisk -l

# Open a disk for editing:
# fdisk /dev/sdc

Command (m for help): m             # show help menu

# Create a new partition:
Command: n
Partition type: p                   # p = primary, e = extended, l = logical
Partition number (1-4): 1           # first primary
First sector: [Enter]               # accept default (start of disk)
Last sector: +20G                   # +size creates partition of that size

# Change partition type (hex code):
Command: t
Partition number: 1
Hex code: 83                        # Linux (default)
Hex code: 82                        # Linux Swap
Hex code: 8e                        # Linux LVM
Hex code: fd                        # Linux RAID autodetect

# Show current partition table:
Command: p

# Write changes and exit:
Command: w

# Inform kernel of partition table changes without reboot:
# partprobe /dev/sdc
# partx -a /dev/sdc                 # alternative
# kpartx /dev/sdc                   # another alternative

File Systems — Deep Dive

A file system is the method by which data is organised and stored on a partition. It defines how files are named, stored, retrieved, and what metadata is kept. Raw partitions without a file system are unusable for storing files — they are just blocks of binary data.

Journaling — The Key to Data Integrity

Journaling is a technique that logs changes to the file system in a dedicated area called the journal before writing them to the actual data area. If the system crashes during a write, the journal allows the file system to replay or roll back the incomplete operation on next boot — recovering a consistent state.

Without journaling (ext2): A crash mid-write could leave the file system in an inconsistent state. Recovery requires running fsck which scans the entire disk — this can take hours on large disks.

With journaling (ext3, ext4, xfs): The journal records what was about to happen. fsck only needs to replay or discard the last journal entry — recovery takes seconds.

Linux File System Comparison

Featureext2ext3ext4xfs
Full nameSecond ExtendedThird ExtendedFourth ExtendedExtended File System
JournalingNoYes (3 modes)Yes (extent-based)Yes (metadata only)
Max file size2 TB2 TB16 TB8 EB
Max filesystem32 TB32 TB1 EB16 EB
Default RHEL3/4567+
Online resizeNoNoGrow onlyGrow only
ExtentsNoNoYesYes
64-bit storageNoNoYesYes

Special File Systems

  • vfat: FAT32, used for shared partitions between Linux and Windows (e.g., USB drives, EFI partition)
  • cdfs: CD-ROM file system for mounting optical media
  • iso9660: Standard for reading .iso image files
  • tmpfs: Temporary file system stored in RAM — fast but lost on reboot (used for /tmp, /run)
  • procfs: Virtual file system at /proc — exposes kernel and process information as files
  • sysfs: Virtual file system at /sys — exposes device and driver information

Inodes — The Core of Linux File Systems

An inode (index node) is a data structure that stores all metadata about a file except its name and its actual data. The inode is the true identity of a file — the filename is just a label pointing to an inode.

What an Inode Contains

  • File type (regular, directory, symlink, device, etc.)
  • Owner (UID) and group (GID)
  • File size in bytes
  • Access, modification, and change timestamps (atime, mtime, ctime)
  • Permission bits (rwxrwxrwx + special bits)
  • Link count (how many directory entries point to this inode)
  • Pointers to data blocks where file content is stored

What an inode does NOT contain: the filename. The filename is stored in the directory entry (a directory is itself a file mapping names to inode numbers).

# View inode number of a file:
# ls -li /etc/passwd
# stat /etc/passwd                  # detailed inode info

# Find files with a specific inode:
# find / -inum 123456

# Check inode usage (exhaustion causes "No space left" even if bytes are free):
# df -ih                            # inode usage per filesystem

Hard Links vs Soft Links — The Inode Connection

Understanding links requires understanding inodes:

Hard Link

A hard link creates a second directory entry pointing to the same inode. Both filenames share exactly the same data, permissions, and metadata. Deleting one does not affect the other — the data is only freed when all hard links are removed (inode link count reaches 0).

  • Hard links can only be created within the same filesystem
  • Hard links cannot be created for directories (to prevent circular references)
  • Hard links have the same inode number as the original
# Create hard link:
# ln /etc/passwd /tmp/passwd_backup
# ls -li /etc/passwd /tmp/passwd_backup  # same inode number

Soft Link (Symbolic Link)

A soft link is a separate file that contains the path to another file. It has its own inode. If the original file is deleted, the symlink becomes a "dangling link" pointing to nothing.

  • Soft links can span different filesystems
  • Soft links can point to directories
  • The link file size equals the length of the path string it contains
# Create soft link:
# ln -s /etc/httpd/conf/httpd.conf /root/httpd.conf

# Verify:
# ls -la /root/httpd.conf           # shows -> /etc/httpd/conf/httpd.conf
# readlink /root/httpd.conf         # shows target path

Mounting File Systems

Mounting attaches a partition's file system to a directory in the Linux filesystem tree. The directory it is attached to is called the mount point. Until mounted, a partition is inaccessible to users.

The /etc/fstab File — Permanent Mounts

The /etc/fstab file defines file systems to be automatically mounted at boot. It has 6 fields:

# Field 1    Field 2    Field 3     Field 4      Field 5   Field 6
# Device     MountPt    FSType      Options       Dump      Fsck
/dev/sda1    /boot      xfs         defaults      1         2
/dev/sda2    swap       swap        defaults      0         0
/dev/sda3    /          xfs         defaults      1         1
UUID=xxxx    /data      ext4        defaults      0         0

Field explanations:

  • Device: Device file, UUID, or LABEL. UUID is preferred — it does not change if disks are reordered.
  • Mount point: Directory where the filesystem is attached. Use swap for swap space.
  • FS type: ext4, xfs, swap, nfs, cifs, tmpfs, etc.
  • Options: Mount options. Common ones: defaults, ro, noexec, nosuid, nodev, _netdev (for network mounts)
  • Dump: 0 = no backup by dump utility; 1 = backed up. Almost always 0 today.
  • Fsck order: 0 = skip; 1 = check first (root); 2 = check after root. Controls boot-time fsck order.

Important Mounting Commands

# Mount temporarily:
# mount /dev/sdc1 /mnt/data

# Mount with specific options:
# mount -o ro,noexec /dev/sdc1 /mnt/data     # read-only, no exec
# mount -o remount,rw /dev/sdc1              # remount as read-write (live)

# Mount all fstab entries:
# mount -a

# View all mounted filesystems:
# mount | column -t
# cat /etc/mtab                              # current mounts
# cat /proc/mounts                          # kernel view of mounts

# Unmount:
# umount /mnt/data
# umount -f /mnt/data                       # force
# umount -l /mnt/data                       # lazy unmount

# Find what is using a mount point:
# fuser -cu /mnt/data                       # who is using it
# lsof /mnt/data                            # open files
# fuser -ck /mnt/data                       # kill those processes

Using UUID and Labels Instead of Device Names

Device names like /dev/sda1 can change if you add or remove disks — the kernel enumerates disks in detection order. A UUID or label is stable regardless of disk order.

# Find UUID and labels of all partitions:
# blkid
# blkid /dev/sda1                   # specific partition

# Assign a label:
# e2label /dev/sdb1 backupdisk      # ext2/3/4
# xfs_admin -L backupdisk /dev/sdb1 # xfs

# Mount by label:
# mount LABEL=backupdisk /mnt/backup

# In /etc/fstab by UUID:
UUID="6f48c79b-ee52-4d64-9c83-..." /mnt/data xfs defaults 0 0

Creating File Systems

# ext4:
# mkfs.ext4 /dev/sdc1
# mkfs.ext4 -b 4096 /dev/sdc1      # specify block size (1024, 2048, 4096)
# mkfs.ext4 -m 2 /dev/sdc1         # reserve only 2% for root (default 5%)

# xfs:
# mkfs.xfs /dev/sdc1
# mkfs.xfs -b size=4096 /dev/sdc1

# Swap:
# mkswap /dev/sdc2
# swapon /dev/sdc2                  # activate
# swapoff /dev/sdc2                 # deactivate
# swapon -s                         # list active swap

# vfat (FAT32):
# mkfs.vfat /dev/sdc1

Swap Space — Virtual Memory Extension

Swap extends the system's effective memory by using disk space when RAM is exhausted. The kernel's memory manager moves least recently used (LRU) memory pages from RAM to swap when RAM fills up. This process is called page-out. When those pages are needed again, they are moved back — page-in.

Swap sizing recommendations:

  • RAM ≤ 2 GB → Swap = 2 × RAM
  • RAM 2–8 GB → Swap = RAM
  • RAM 8–64 GB → Swap = 4–8 GB
  • RAM > 64 GB → Swap = 4 GB minimum (most modern DBs use hugepages, not swap)
# Create swap partition:
# fdisk /dev/sdb (create partition, set type 82)
# mkswap /dev/sdb2
# swapon /dev/sdb2
# echo "/dev/sdb2 swap swap defaults 0 0" >> /etc/fstab

# Create swap file (when no partition available):
# dd if=/dev/zero of=/swapfile bs=1M count=4096
# chmod 600 /swapfile               # security — only root should read swap
# mkswap /swapfile
# swapon /swapfile
# echo "/swapfile swap swap defaults 0 0" >> /etc/fstab

# Monitor swap usage:
# free -h
# vmstat 1 5                        # si/so columns show swap activity
# swapon --show                     # detailed swap info

File System Integrity — fsck and e2fsck

fsck (file system check) verifies and repairs file system consistency. It must be run on unmounted file systems — running fsck on a mounted filesystem will corrupt it.

The Five Phases of fsck

  1. Phase 1 — Check blocks and sizes: Scans all inodes, verifies block pointers are valid and within range.
  2. Phase 2 — Check path names: Walks the directory tree, verifies all directory entries point to valid inodes.
  3. Phase 3 — Check connectivity: Ensures all directories are connected to the root tree (no orphaned directories).
  4. Phase 4 — Check reference counts: Verifies inode link counts match the number of directory entries pointing to each inode.
  5. Phase 5 — Check free blocks: Verifies the free block bitmap matches the actual free blocks.
# Basic file system check:
# umount /dev/sdc1                  # MUST unmount first
# fsck /dev/sdc1

# Auto-fix without prompts:
# e2fsck -p /dev/sdc1               # automatically repair common issues
# fsck -AR -y                       # check all filesystems, auto-fix all

# Check specific type:
# fsck -t ext4 /dev/sdc1
# fsck -AR -t no,ext3 -y            # check all EXCEPT ext3

# Dry run (report only):
# fsck -n /dev/sdc1

# Check journal status:
# tune2fs -l /dev/sdc1 | grep -i journal

Superblock — The Filesystem's Control Record

The superblock is a critical metadata area at the beginning of each partition that describes the entire file system. It contains:

  • Total blocks and inodes in the filesystem
  • Number of free blocks and inodes
  • Block size and fragment size
  • Mount count and maximum mount count
  • Last mount time, last write time
  • File system state (clean/dirty)

Because the superblock is so critical, ext file systems store multiple backup copies of the superblock at regular intervals. If the primary superblock is corrupted (e.g., from a hardware failure mid-write), you can restore from a backup.

# List all superblock locations:
# mke2fs -n /dev/sdc1               # shows superblock backup locations without formatting
# dumpe2fs /dev/sdc1 | grep superblock

# Repair using backup superblock:
# e2fsck -b 32768 /dev/sdc1         # use superblock at block 32768

# View filesystem metadata:
# tune2fs -l /dev/sdc1              # all superblock info

# Reserve space for root user (default 5%):
# tune2fs -m 2 /dev/sdc1            # reduce to 2%

# Convert ext2 to ext3 (add journaling):
# tune2fs -j /dev/sdc1

# Convert ext3 to ext4:
# tune2fs -O extents,uninit_bg,dir_index /dev/sdc1

Disk Usage Monitoring

# Filesystem usage (per-mount):
# df -hT                            # human-readable with filesystem type

# Directory and file sizes:
# du -sh /var/log                   # size of specific directory
# du -h /var | sort -rh | head -10  # top 10 by size

# Find disk usage of all top-level directories:
# du -sh /* 2>/dev/null | sort -rh | head -20

# Find files over 100 MB:
# find / -size +100M -type f 2>/dev/null

# Find files newer than 7 days and larger than 10MB:
# find /var -mtime -7 -size +10M

# Inode exhaustion check (can cause "No space" even with bytes free):
# df -ih

Common Real-World Scenarios

Scenario 1: Filesystem Full Despite Apparent Free Space

# Symptom: "No space left on device" but df shows free space
# Cause 1: Inode exhaustion
# df -ih                            # check inode usage
# find / -type f | wc -l            # count all files (high number = inode pressure)

# Cause 2: Files deleted but still held open by running process
# lsof | grep deleted | awk '{print $1, $2, $7, $8, $9}'
# The process holds the file descriptor; disk space not freed until process releases it
# Solution: restart the process, or: cat /dev/null > /proc/PID/fd/FD_NUMBER

Scenario 2: Corrupted Filesystem at Boot

# System drops to emergency shell with "filesystem error"
# 1. Boot to rescue mode or single user mode
# 2. Check the root filesystem:
# umount /                          # if possible
# fsck -y /dev/sda1                 # or e2fsck -y
# If root cannot be unmounted, use rescue disk
# 3. If superblock corrupted:
# dumpe2fs /dev/sda1 | grep superblock
# e2fsck -b 32768 /dev/sda1
# 4. Reboot: reboot -f

Scenario 3: Disk Full — Free Space Fast

# Find biggest log files:
# find /var/log -name "*.log" -size +100M -exec ls -lh {} \;

# Truncate (clear) a log without deleting (process keeps fd open):
# > /var/log/large.log              # truncate to zero
# : > /var/log/large.log            # alternative

# Find and remove old core dumps:
# find / -name "core" -type f -delete

# Clean yum/dnf cache:
# yum clean all / dnf clean all

Advanced: Disk Health Monitoring

# Check disk health with smartctl (requires smartmontools):
# yum install smartmontools -y
# smartctl -H /dev/sda              # health check
# smartctl -i /dev/sda              # device information
# smartctl -a /dev/sda              # full report

# Key smartctl fields:
# Reallocated_Sector_Ct: non-zero = disk sectors failing (replace soon)
# Current_Pending_Sector: unstable sectors
# Offline_Uncorrectable: unrecoverable errors
# Rule: if THRESH > VALUE field, disk needs immediate replacement

# Check disk I/O errors from kernel:
# dmesg | grep -i "error\|fail\|I/O error"
# cat /var/log/messages | grep "sd[a-z]"