Disk management and filesystems
In this series (15 parts)
- What is Linux and how it differs from other OSes
- Installing Linux and setting up your environment
- The Linux filesystem explained
- Users, groups, and permissions
- Essential command line tools
- Shell scripting fundamentals
- Processes and job control
- Standard I/O, pipes, and redirection
- The Linux networking stack
- Package management and software installation
- Disk management and filesystems
- Logs and system monitoring
- SSH and remote access
- Cron jobs and task scheduling
- Linux security basics for sysadmins
Every piece of data on your Linux system lives on a block device: a hard drive, SSD, or virtual disk. Managing these devices means partitioning them, creating filesystems on the partitions, and mounting those filesystems into the directory tree. This article covers the full workflow.
Prerequisites
You should understand the Linux filesystem layout and be comfortable with command line tools.
Block devices
A block device is a storage device that reads and writes in fixed-size blocks. Check your block devices:
lsblk
Output:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 500G 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
├─sda2 8:2 0 480G 0 part /
└─sda3 8:3 0 19.5G 0 part [SWAP]
sdb 8:16 0 100G 0 disk
graph TD A[Physical Disk /dev/sdb 100GB] --> B[Partition Table GPT/MBR] B --> C[Partition 1 /dev/sdb1 50GB] B --> D[Partition 2 /dev/sdb2 50GB] C --> E[Filesystem ext4] D --> F[Filesystem xfs] E --> G[Mount point /data] F --> H[Mount point /backup] style A fill:#64b5f6,stroke:#1976d2,color:#000 style E fill:#81c784,stroke:#388e3c,color:#000 style F fill:#81c784,stroke:#388e3c,color:#000
sda is your first disk with three partitions. sdb is a second disk with no partitions yet.
# More detail about disk sizes
sudo fdisk -l /dev/sdb
Output:
Disk /dev/sdb: 100 GiB, 107374182400 bytes, 209715200 sectors
Disk model: Virtual disk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
Partition tables: MBR vs GPT
| Feature | MBR | GPT |
|---|---|---|
| Max disk size | 2 TB | 9.4 ZB (effectively unlimited) |
| Max partitions | 4 primary (or 3 + extended) | 128 |
| Boot mode | BIOS | UEFI |
| Redundancy | None | Backup table at end of disk |
Use GPT for any modern system. MBR is only needed for legacy BIOS systems.
Checking disk space
# Disk usage summary by filesystem
df -h
Output:
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 480G 123G 333G 27% /
/dev/sda1 511M 12M 500M 3% /boot/efi
tmpfs 7.8G 45M 7.8G 1% /tmp
# Directory sizes
du -sh /var/log/* 2>/dev/null | sort -rh | head -10
Output:
234M /var/log/journal
45M /var/log/syslog
12M /var/log/kern.log
8.5M /var/log/auth.log
3.2M /var/log/dpkg.log
# Find what is using the most space
du -sh /* 2>/dev/null | sort -rh | head -10
Output:
123G /home
45G /var
12G /usr
1.2G /opt
456M /boot
Example 1: Partition a disk, create ext4, and mount it
Let’s set up the unused /dev/sdb disk. We will create two partitions: one for data (80GB) and one for backups (20GB).
Step 1: Create partitions with fdisk
sudo fdisk /dev/sdb
Inside fdisk:
Command (m for help): g # Create new GPT partition table
Created a new GPT disklabel.
Command (m for help): n # New partition
Partition number (1-128, default 1): 1
First sector (2048-209715166, default 2048):
Last sector: +80G
Created a new partition 1 of type 'Linux filesystem' and of size 80 GiB.
Command (m for help): n # Second partition
Partition number (2-128, default 2): 2
First sector (167774208-209715166, default 167774208):
Last sector (167774208-209715166, default 209715166): # Use remaining space
Created a new partition 2 of type 'Linux filesystem' and of size 20 GiB.
Command (m for help): p # Print partition table
Device Start End Sectors Size Type
/dev/sdb1 2048 167774207 167772160 80G Linux filesystem
/dev/sdb2 167774208 209715166 41940959 20G Linux filesystem
Command (m for help): w # Write and exit
The partition table has been altered.
Verify:
lsblk /dev/sdb
Output:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:16 0 100G 0 disk
├─sdb1 8:17 0 80G 0 part
└─sdb2 8:18 0 20G 0 part
Step 2: Create filesystems
# ext4 for the data partition
sudo mkfs.ext4 -L data /dev/sdb1
Output:
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 20971520 4k blocks and 5242880 inodes
Filesystem UUID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
# ext4 for the backup partition
sudo mkfs.ext4 -L backup /dev/sdb2
Step 3: Create mount points and mount
# Create directories
sudo mkdir -p /data /backup
# Mount the partitions
sudo mount /dev/sdb1 /data
sudo mount /dev/sdb2 /backup
# Verify
df -h /data /backup
Output:
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 79G 24K 75G 1% /data
/dev/sdb2 20G 24K 19G 1% /backup
Step 4: Make mounts permanent with fstab
Without fstab entries, the mounts will be lost on reboot.
# Get the UUIDs (more reliable than device names)
sudo blkid /dev/sdb1 /dev/sdb2
Output:
/dev/sdb1: LABEL="data" UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="ext4"
/dev/sdb2: LABEL="backup" UUID="f1e2d3c4-b5a6-7890-cdef-123456789abc" TYPE="ext4"
# Back up fstab first!
sudo cp /etc/fstab /etc/fstab.bak
# Add entries
echo 'UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 /data ext4 defaults 0 2' | sudo tee -a /etc/fstab
echo 'UUID=f1e2d3c4-b5a6-7890-cdef-123456789abc /backup ext4 defaults 0 2' | sudo tee -a /etc/fstab
# Test fstab syntax (unmount and remount all)
sudo umount /data /backup
sudo mount -a
# Verify
df -h /data /backup
The fstab fields:
UUID=... /data ext4 defaults 0 2
| | | | | |
device mount fs options dump fsck
point type order
defaults= rw, suid, dev, exec, auto, nouser, async0= do not dump (backup)2= check filesystem second (after root /)
Example 2: Check disk health and usage
Monitor your disks to catch problems before they cause data loss:
# Check filesystem for errors (must be unmounted)
sudo umount /data
sudo fsck -f /dev/sdb1
Output:
e2fsck 1.47.0 (5-Feb-2023)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
data: 11/5242880 files (0.0% non-contiguous), 420325/20971520 blocks
# Remount after check
sudo mount /data
# Check SMART health (for physical disks)
sudo apt install smartmontools -y
sudo smartctl -a /dev/sda | head -30
Output:
=== START OF INFORMATION SECTION ===
Model Family: Samsung SSD 870
Device Model: Samsung SSD 870 EVO 500GB
Serial Number: S1234567890
Firmware Version: SVT04B6Q
User Capacity: 500,107,862,016 bytes [500 GB]
SMART overall-health self-assessment test result: PASSED
# Monitor I/O in real time
iostat -x 1 3
Output:
Device r/s w/s rkB/s wkB/s %util
sda 12.00 45.00 480.00 1800.00 5.20
sdb 0.00 2.00 0.00 32.00 0.10
LVM basics
LVM (Logical Volume Manager) adds a layer of abstraction between physical disks and filesystems. It lets you resize volumes, span multiple disks, and take snapshots.
# Install LVM tools
sudo apt install lvm2 -y
# Create a physical volume
sudo pvcreate /dev/sdc
# Create a volume group
sudo vgcreate mygroup /dev/sdc
# Create a logical volume (50GB)
sudo lvcreate -L 50G -n mydata mygroup
# Create a filesystem on the LV
sudo mkfs.ext4 /dev/mygroup/mydata
# Mount it
sudo mkdir /mydata
sudo mount /dev/mygroup/mydata /mydata
# Extend the volume later (add 20GB)
sudo lvextend -L +20G /dev/mygroup/mydata
sudo resize2fs /dev/mygroup/mydata
The main advantage: you can resize volumes without unmounting them (for ext4 with resize2fs). This is critical for production servers where downtime is expensive.
What comes next
The next article covers Logs and system monitoring, where you will learn to read system logs, use journalctl, and track down problems.
For the security perspective on disk management, understanding where data lives is essential for incident response and forensic analysis.