Block devices and partitions
A block device is a disk exposed as a file in /dev. lsblk shows the tree of devices and partitions. A partition is just a byte range on the device — GPT and MBR are the two schemes that record where those ranges start and end.
You add a second disk to a server. Linux immediately sees it — but before you can store a single file on it, you need to understand what Linux actually exposes to you, what a “partition” really is, and why the same disk can appear as /dev/sda, /dev/nvme0n1, or /dev/vda depending on the hardware. Skip this foundation and you will spend hours confused at error messages like “no medium found” or “device or resource busy” when you try to format or mount the wrong node.
Storage in Linux is built in three distinct layers: raw block device → partition → filesystem. This lesson covers the bottom two.
After this lesson you can read lsblk output and identify disks vs partitions, explain what /dev/sda, /dev/sdb1, and /dev/nvme0n1p2 mean, explain the difference between GPT and MBR partition tables and when each is used, and describe why a partition is just a byte range on a block device.
Linux exposes every storage device as a file under /dev. This is the everything-is-a-file principle applied to hardware. A block device file lets the kernel, and programs with the right permissions, read and write raw bytes to the device in fixed-size chunks called blocks (usually 512 bytes or 4 KiB).
# List block devices and their files
ls -l /dev/sd* /dev/nvme* 2>/dev/null
# brw-rw---- 1 root disk 8, 0 Jun 21 09:00 /dev/sda
# brw-rw---- 1 root disk 8, 1 Jun 21 09:00 /dev/sda1
# brw-rw---- 1 root disk 8, 2 Jun 21 09:00 /dev/sda2
# brw-rw---- 1 root disk 259, 0 Jun 21 09:00 /dev/nvme0n1
# brw-rw---- 1 root disk 259, 1 Jun 21 09:00 /dev/nvme0n1p1
# 'b' at the start = block device (vs 'c' = char device, '-' = regular file)
# The numbers (8, 0) are major:minor — major identifies the driver, minor the specific deviceThe naming convention encodes the hardware type:
/dev/sda— SCSI or SATA disk (also used for USB drives and most VMs);b= second disk,c= third./dev/nvme0n1— NVMe SSD;nvme0= first NVMe controller,n1= first namespace on that controller./dev/vda— virtio disk (KVM/QEMU VMs)./dev/mmcblk0— eMMC or SD card (Raspberry Pi, embedded boards).
lsblk is the right tool for understanding your disk topology. It prints a tree of block devices and their partitions, with sizes and mount points. Run it before touching any disk.
lsblk
# 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 1G 0 part /boot
# └─sda3 8:3 0 498.5G 0 part /
# nvme0n1 259:0 0 1T 0 disk
# └─nvme0n1p1 259:1 0 1T 0 part /data
# Show filesystem type and UUID (useful before editing fstab)
lsblk -f
# NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
# sda
# ├─sda1 vfat FAT32 C7A2-1234 505.4M 1% /boot/efi
# ├─sda2 ext4 1.0 a1b2c3d4-... 800.5M 13% /boot
# └─sda3 ext4 1.0 e5f6a7b8-... 390.1G 17% /
# nvme0n1
# └─nvme0n1p1 xfs 9f8e7d6c-... 950.2G 5% /data
# Show sizes in bytes (for scripts)
lsblk -b -o NAME,SIZE,TYPEKey columns: NAME (device file), SIZE (human-readable by default), TYPE (disk = whole device, part = partition, lvm = LVM logical volume), MOUNTPOINTS (where it is mounted, if at all).
A partition is nothing more than a byte range on the block device. The partition table at the start of the disk records a list of these ranges: “partition 1 starts at sector 2048, ends at sector 1050623”. The kernel reads this table at boot and creates a device node for each entry (/dev/sda1, /dev/sda2, etc.).
# See the raw partition table (GPT disk)
sudo fdisk -l /dev/sda
# Disk /dev/sda: 500 GiB, 536870912000 bytes, 1048576000 sectors
# Disk model: Samsung SSD 870
# Units: sectors of 1 * 512 = 512 bytes
# Sector size (logical/physical): 512 bytes / 512 bytes
# I/O size (minimum/optimal): 512 bytes / 512 bytes
# Disklabel type: gpt
#
# Device Start End Sectors Size Type
# /dev/sda1 2048 1050623 1048576 512M EFI System
# /dev/sda2 1050624 3147775 2097152 1G Linux filesystem
# /dev/sda3 3147776 1048573951 1045426176 498.5G Linux filesystem
# The 'Start' and 'End' columns are sector numbers
# Partition size = (End - Start + 1) * sector_size
# sda1 = (1050623 - 2048 + 1) * 512 = 536,870,912 bytes = 512 MiBWhy partition at all? Three reasons:
- Isolation: a runaway process filling
/var/logdoes not also fill/and crash the whole system. - Different mount options:
/tmponnoexec,/homeonnosuid. - Different filesystems:
/bootasext4,/boot/efiasvfat(required by UEFI).
GPT vs MBR: which partition table format is on the disk. This matters because MBR has hard limits that GPT removes.
# Check which type a disk uses
sudo fdisk -l /dev/sda | grep 'Disklabel type'
# Disklabel type: gpt
# Or use parted
sudo parted /dev/sda print | grep 'Partition Table'
# Partition Table: gpt
| Feature | MBR (Master Boot Record) | GPT (GUID Partition Table) |
|---|---|---|
| Max disk size | 2 TiB | 9.4 ZiB (effectively unlimited) |
| Max partitions | 4 primary (or 3 + extended) | 128 (by default) |
| Redundancy | Single copy at sector 0 | Header + backup copy at end of disk |
| Boot firmware | BIOS (legacy) | UEFI (modern); BIOS-GPT also works |
| Introduced | 1983 | 2000 (part of EFI spec) |
Rule of thumb: any disk over 2 TiB must use GPT. Any new system with UEFI firmware should use GPT. MBR is only for legacy hardware or when you need to dual-boot with very old systems.
The critical failure mode: if you accidentally run fdisk in MBR mode on a disk that was GPT, you overwrite the GPT header with an MBR. The data is still there but the partition table is gone. gdisk or gparted rescue tools can sometimes recover the backup GPT copy from the end of the disk.
/dev/sda vs /dev/sda1 is a critical distinction. The whole disk vs a partition. Formatting or zeroing the whole disk (/dev/sda) destroys the partition table. Formatting a partition (/dev/sda1) only touches that partition’s byte range.
# SAFE: format just the partition (the filesystem lives here)
sudo mkfs.ext4 /dev/sda3
# DANGEROUS: this writes to the raw disk, destroying the partition table
# sudo mkfs.ext4 /dev/sda <-- do NOT do this unless you want a disk with one big filesystem and no partition table
# Check what is mounted before touching anything
mount | grep sda
# If anything shows up, umount first — you cannot safely format a mounted partition
# Verify you have the right device — double-check size
lsblk /dev/sda
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 500G 0 diskA quick sanity check before any destructive operation: lsblk the target device, confirm the size matches what you expect (plugging in /dev/sdb when you meant /dev/sdc is a classic data-loss event), and confirm it is not mounted.
Scenario: you just attached a new 2 TiB NVMe drive to a server and need to prepare it for use.
# Step 1: confirm the kernel saw it
lsblk
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# nvme0n1 259:0 0 2T 0 disk <- new disk, no partitions yet
# nvme1n1 259:1 0 500G 0 disk
# └─nvme1n1p1 259:2 0 500G 0 part /
# Step 2: verify it is not mounted and check for an existing partition table
sudo fdisk -l /dev/nvme0n1
# Disk /dev/nvme0n1: 2 TiB, 2199023255552 bytes, 4294967296 sectors
# Disk /dev/nvme0n1 does not contain a recognized partition table.
# 2 TiB > 2 TiB MBR limit would be fine with GPT; always use GPT for new disks
# Step 3: create a GPT partition table and a single partition
sudo fdisk /dev/nvme0n1
# (inside fdisk)
# g <- create new GPT table
# n <- new partition
# 1 <- partition number 1
# (enter) <- accept default start sector
# (enter) <- accept default end sector (uses all space)
# w <- write and exit
# Step 4: verify
lsblk /dev/nvme0n1
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# nvme0n1 259:0 0 2T 0 disk
# └─nvme0n1p1 259:1 0 2T 0 part <- partition ready for a filesystemThe disk is now partitioned. The next step (next lesson) is creating a filesystem inside /dev/nvme0n1p1.
▸Why this works
On macOS, disks appear as /dev/disk0, /dev/disk1, etc., with partitions as /dev/disk0s1, /dev/disk0s2. The diskutil list command is the macOS equivalent of lsblk. macOS uses GPT exclusively on Intel Macs and Apple Silicon, and formats partitions with APFS or HFS+. There is no /dev/sda — the naming is entirely different. Cross-platform scripts that hardcode Linux device names will silently fail or hit the wrong device on macOS.
▸Common mistake
A common mistake on cloud VMs: the root disk appears as /dev/xvda (Xen) or /dev/vda (KVM) rather than /dev/sda. Scripts that assume /dev/sda will fail or — worse — try to operate on a device that does not exist, or on whatever happens to be at that path. Always use lsblk to discover actual device names in a given environment. Never hardcode /dev/sda in automation.
You run lsblk and see /dev/nvme0n1 (2 TiB, TYPE=disk) with no partitions. What does this mean, and what is the first thing you must do before you can store files on it?
Linux exposes every storage device as a block device file under /dev. The naming convention (sda, nvme0n1, vda) reflects the hardware interface. lsblk is the first command you run to understand disk topology — it shows the tree of devices and partitions with sizes and mount points. A partition is a byte range on the raw device, recorded in a partition table at the start of the disk. GPT is the modern format (supports >2 TiB, 128 partitions, redundant headers) and should be used on all new systems; MBR is the legacy format for BIOS systems and disks under 2 TiB. The whole-disk device (/dev/sda) and a partition on it (/dev/sda1) are different — formatting the whole disk destroys the partition table. Always lsblk before any destructive operation.
Practice
Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.
Something unclear?
Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.