
This lesson builds a mental model of Linux storage and teaches the daily tools for working with disks and filesystems. It uses a virtual machine example so the workflow is safe to practice.
Block device is a disk or partition exposed under /dev. Partition divides a disk into sections. Filesystem organizes files on a partition or device. Mount attaches a filesystem to a directory so it becomes part of the tree.
Prerequisites
- Day 1 through Day 10 completed
- A VM where an extra virtual disk can be added, or permission to create a loopback device
Inspect devices and layout
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,LABEL,UUID
# tree view of mounts by source and target
findmnt -A | head -30
# kernel messages for storage
sudo dmesg | grep -iE 'sd[a-z]|nvme|virtio' | tail -20Typical device names:
- SATA or SCSI:
/dev/sda,/dev/sdband partitions/dev/sda1,/dev/sda2 - NVMe:
/dev/nvme0n1and partitions/dev/nvme0n1p1 - Virtual disks under KVM or QEMU:
vda,vdb
Add a new virtual disk in a VM (safe path)
- Shut down the VM and add a second disk in the hypervisor UI, for example 5 GB.
- Boot and confirm it appears as an unpartitioned device.
lsblk -o NAME,TYPE,SIZE,FSTYPE | grep -E 'disk|part'If adding a real disk is not possible, create a loopback device from a file for practice.
# create a 2 GiB sparse file as a demo disk
sudo fallocate -l 2G /var/tmp/disk.img
sudo losetup --find --show /var/tmp/disk.img # prints /dev/loopX
lsblk -o NAME,TYPE,SIZE /dev/loop*Verify the target device carefully. Formatting the wrong device destroys data. Double check with lsblk and size column before running any command that writes structures.
Partition the disk
Use parted for a quick guided setup. GPT is recommended for modern systems.
DISK=/dev/sdb # replace with your device or the loop device
sudo parted -s $DISK mklabel gpt
sudo parted -s $DISK mkpart primary ext4 1MiB 100%
sudo parted -s $DISK printThe new partition appears as $DISK1 such as /dev/sdb1 or /dev/loop0p1.
Alternative with fdisk (interactive):
sudo fdisk /dev/sdb
# n (new) p (primary) 1, accept defaults, w (write)Make a filesystem and mount it
Create an ext4 filesystem and a mount point.
PART=/dev/sdb1 # adjust to match your partition
sudo mkfs.ext4 -L data1 $PART
sudo mkdir -p /mnt/data1
sudo mount $PART /mnt/data1
# confirm
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT $PART
findmnt /mnt/data1Test write access.
sudo sh -c 'echo test > /mnt/data1/hello.txt'
sudo ls -l /mnt/data1Unmount when done or before making it persistent.
sudo umount /mnt/data1ext4 is a solid default. XFS performs well on large files and servers. Btrfs adds snapshots and checksums. Choose based on needs and distribution defaults.
Persistent mounts with /etc/fstab
Mounts added at runtime vanish after reboot. Use /etc/fstab for persistence, preferably by UUID or label.
Find the UUID and label.
blkid $PARTAdd a line to /etc/fstab.
# backup first
sudo cp /etc/fstab /etc/fstab.bak
# example using UUID and ext4 defaults
UUID=$(blkid -s UUID -o value $PART)
LINE="UUID=$UUID /mnt/data1 ext4 defaults,nofail 0 2"
echo "$LINE" | sudo tee -a /etc/fstab
# test without reboot
sudo mount -a
findmnt /mnt/data1Notes:
nofailallows boot to continue if the device is not present.- The final
2enablesfsckorder. Root is usually1, others2.
Keep a backup and test with mount -a. If a system fails to boot, use a rescue shell to comment out bad lines or fix the device names.
Space and usage checks
# filesystem space and type
df -hT
# disk usage by directory, current level
du -sh * | sort -h
# restrict to one filesystem and go two levels deep
du -h -x --max-depth=2 /var | sort -h | tail -20Combine find with size tests.
sudo find / -xdev -type f -size +1G -printf '%p %s bytes\n' 2>/dev/null | headLabels and tuning
Labels and tunables help identify and optimize filesystems.
# set or change an ext4 label
sudo e2label $PART projects
# show and tweak ext4 parameters
tune2fs -l $PART | head -20Mount options influence performance and safety.
noatimereduces write amplification on frequently read filesnodev,nosuid,noexecreduce risk on untrusted media
Example temporary mount with options:
sudo mount -o noatime,nodev /dev/sdb1 /mnt/data1Persist options by adding them in the fstab options column.
Create and manage a swapfile (optional)
A swapfile is flexible and avoids repartitioning.
# create a 2 GiB swapfile
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# persist across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# verify
swapon --show
free -hSwap writes frequently. On modern SSDs this is acceptable, but monitor wear on systems with heavy swapping. Prefer more RAM if possible.
Check and repair filesystems
For ext filesystems, fsck checks integrity when a filesystem is unmounted.
sudo umount /mnt/data1
sudo fsck -f $PARTDo not run fsck on a mounted, writable filesystem.
Ext4 journals metadata. After an unclean shutdown, the journal replays changes quickly. fsck still runs periodically based on mount counts or intervals.
Practical lab
- Create a new partition and ext4 filesystem on a secondary disk or loop device, then mount it at
/mnt/data1.
# substitute your device
DISK=/dev/sdb
PART=/dev/sdb1
sudo parted -s $DISK mklabel gpt
sudo parted -s $DISK mkpart primary ext4 1MiB 100%
sudo mkfs.ext4 -L data1 $PART
sudo mkdir -p /mnt/data1
sudo mount $PART /mnt/data1- Make the mount persistent by UUID with safe options.
UUID=$(blkid -s UUID -o value $PART)
echo "UUID=$UUID /mnt/data1 ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
sudo mount -a
findmnt /mnt/data1- Generate space and measure it.
sudo dd if=/dev/zero of=/mnt/data1/bigfile bs=100M count=5 status=progress
sudo du -sh /mnt/data1
sudo df -hT | grep data1- Optional: create a 1 GiB swapfile and verify it is active.
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
swapon --show- Clean up the practice environment if using a loop device.
sudo swapoff /swapfile && sudo rm -f /swapfile || true
sudo umount /mnt/data1 || true
sudo losetup -D || true
sudo rm -f /var/tmp/disk.img || trueTroubleshooting
device is busywhen unmounting. Close terminals, stop services using the mount, or uselsof +f -- /mnt/data1to find holders.unknown filesystem typeafter creating a filesystem. Confirm the correctmkfstool was used and that the kernel supports the type.- Mount fails on boot. Use
nofailin/etc/fstab, verify UUIDs, and test withmount -a. Check logs withjournalctl -b -u systemd-fsckandjournalctl -b. - Permission issues on shared data directories. Use correct ownership and group settings, for example
sudo chown -R root:developers /mnt/data1/projects && sudo chmod -R 2775 /mnt/data1/projects. - Swapfile cannot be enabled. Ensure file mode is
600and that a sparse file is not on a filesystem withnocowoptions that block swap on some filesystems.
Up next: Day 12 - Finding Things and Text Processing I
Day 12 begins text processing with grep, cut, sort, uniq, wc, and tee. It focuses on searching and shaping logs and command output into quick reports.