Linux Storage & Filesystems
Partitions, LVM, RAID, filesystems, and disk health — lsblk, fdisk, lvm, mdadm, mkfs, fsck, and smartctl
┌─────────────────────────────────────────────────────┐ │ Application (read / write) │ └──────────────────────┬──────────────────────────────┘ │ syscall (read, write, open) ┌──────────────────────▼──────────────────────────────┐ │ VFS (Virtual Filesystem) │ │ page cache · dentries · inodes │ └──────────┬────────────────────────────┬─────────────┘ │ │ ┌──────────▼──────────┐ ┌─────────────▼─────────────┐ │ ext4 / xfs / │ │ tmpfs / proc / sysfs │ │ btrfs / vfat │ │ (pseudo-filesystems) │ └──────────┬──────────┘ └────────────────────────────┘ │ block I/O requests ┌──────────▼──────────────────────────────────────────┐ │ Block Device Layer │ │ I/O scheduler · bio merging · queues │ └──────────┬──────────────────────────────────────────┘ │ ┌──────▼──────┐ ┌────────────────────┐ │ LVM (dm) │◄───────►│ md RAID (md0 …) │ │ vg0/data │ │ RAID 0/1/5/6/10 │ └──────┬──────┘ └────────┬───────────┘ │ │ ┌──────────▼─────────────────────────▼───────────────┐ │ Physical Block Devices (/dev/sda, nvme0n1) │ │ HDD · SSD · NVMe · iSCSI │ └─────────────────────────────────────────────────────┘
lsblk / blkid Storage

Enumerate block devices, show topology, filesystem types, UUIDs, and labels. Use these as your first commands when exploring storage layout on an unfamiliar system.

List block devices

Shell
lsblk                          # tree view of all block devices
lsblk -f                       # include FSTYPE, LABEL, UUID, MOUNTPOINT
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT
lsblk -d -o NAME,SIZE,ROTA,MODEL  # disks only; ROTA=0 means SSD
lsblk -p                       # full device paths (/dev/sda not sda)

Example output — lsblk -f

Output
NAME        FSTYPE      LABEL   UUID                                   MOUNTPOINT
sda
├─sda1      vfat                ABCD-1234                              /boot/efi
├─sda2      ext4                a1b2c3d4-...                           /boot
└─sda3      LVM2_member         e5f6g7h8-...
  ├─vg0-root ext4               11223344-...                           /
  └─vg0-data ext4               55667788-...                           /data
sdb         (no partitions yet)

blkid — show UUID and FSTYPE

Shell
blkid                          # all devices
blkid /dev/sdb1                # specific partition
blkid -o value -s UUID /dev/sdb1  # print UUID only
blkid -t TYPE=ext4             # find all ext4 devices

Identify SSDs vs HDDs

Shell
lsblk -d -o NAME,SIZE,ROTA,MODEL
# ROTA=1 → rotational (HDD), ROTA=0 → SSD/NVMe
cat /sys/block/sda/queue/rotational  # 0=SSD, 1=HDD
cat /sys/block/nvme0n1/queue/rotational
Tiplsblk -f is the fastest way to confirm a disk is unmounted and has no filesystem before formatting it.
fdisk / gdisk / parted Partitions

Manage partition tables. Use fdisk for MBR disks (<2 TB), gdisk for GPT, or parted for both with scripted/non-interactive support.

List partition tables

Shell
fdisk -l                       # list all disks and partitions
fdisk -l /dev/sdb               # specific disk
parted -l                       # parted equivalent
parted /dev/sdb print            # non-interactive listing

Interactive fdisk — create MBR partition

Shell
fdisk /dev/sdb
# Inside fdisk interactive mode:
#   p  — print current partition table
#   n  — new partition (then p=primary, e=extended)
#   t  — change partition type (L lists codes)
#   d  — delete partition
#   w  — write changes and exit
#   q  — quit without saving

gdisk — GPT partitions

Shell
gdisk /dev/sdb
# Same basic commands as fdisk (n, d, p, w, q)
# GPT partition type codes differ: 8300=Linux, 8200=swap,
# 8e00=Linux LVM, fd00=Linux RAID, ef00=EFI System

parted — non-interactive / scripted

Shell
# Create a GPT label and partitions non-interactively
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary ext4 1MiB 100%
parted /dev/sdb set 1 lvm on

# Resize a partition (increase to 50 GiB)
parted /dev/sdb resizepart 1 50GiB

# Align check
parted /dev/sdb align-check optimal 1

Partition type codes

TypeMBR CodeGPT Code (gdisk)Notes
Linux filesystem838300Default for ext4, xfs, btrfs
Linux swap828200Swap space
Linux LVM8e8e00Physical volumes for LVM
Linux RAIDfdfd00Used with mdadm
EFI Systemefef00UEFI boot partition, must be FAT32
BIOS bootef02GRUB BIOS boot on GPT
Partition alignmentAlways start partitions on a 1 MiB boundary (2048 sectors) for optimal SSD/NVMe and RAID performance. parted does this automatically when you use MiB/GiB units.
LVM Volumes

Logical Volume Manager provides a flexible abstraction layer between physical disks and filesystems. LVM allows online resizing, snapshots, and spanning volumes across multiple disks.

LVM changes are liveMost LVM operations (extend, create, snapshot) take effect immediately without rebooting or unmounting. However, the filesystem on top of an LV must also be resized after extending the LV.

Physical volumes (PV)

Shell
pvcreate /dev/sdb1             # initialize a partition as a PV
pvcreate /dev/sdb              # or use a whole disk (no partition table)
pvdisplay                      # verbose PV info
pvdisplay /dev/sdb1            # specific PV
pvs                            # compact PV list
pvremove /dev/sdb1             # remove PV metadata (wipes it from LVM)
pvmove /dev/sdb1               # migrate PEs off a PV before removal

Volume groups (VG)

Shell
vgcreate vg0 /dev/sdb1         # create VG named vg0 from PV
vgcreate vg0 /dev/sdb1 /dev/sdc1  # VG spanning two PVs
vgdisplay vg0                  # verbose VG info
vgs                            # compact VG list
vgextend vg0 /dev/sdc1         # add a new PV to existing VG
vgreduce vg0 /dev/sdb1         # remove a PV from VG (must have no LVs)
vgremove vg0                   # delete VG (all LVs must be removed first)
vgrename vg0 vg-production     # rename a VG

Logical volumes (LV)

Shell
lvcreate -L 10G -n data vg0      # create 10 GiB LV named "data"
lvcreate -l 100%FREE -n data vg0  # use all free space
lvcreate -l 50%VG -n data vg0    # use 50% of VG
lvdisplay /dev/vg0/data         # verbose LV info
lvs                             # compact LV list
lvremove /dev/vg0/data          # delete LV (must be unmounted first)
lvrename vg0 data archive       # rename an LV

Extend an LV and resize filesystem

Shell
# Extend LV by 5 GiB
lvextend -L +5G /dev/vg0/data

# Resize filesystem to fill the new LV size
resize2fs /dev/vg0/data         # ext4 (can be done live)
xfs_growfs /mnt/data            # xfs (use mount point, not device)

# Shortcut: extend LV and resize ext4/xfs in one command
lvextend -L +5G -r /dev/vg0/data  # -r calls resize2fs/fsadm automatically

LVM snapshots

Shell
# Create a snapshot (CoW — needs space for changed blocks)
lvcreate -L 1G -s -n snap /dev/vg0/data

# Mount the snapshot read-only
mount -o ro /dev/vg0/snap /mnt/snap

# Restore from snapshot (merge back)
lvconvert --merge /dev/vg0/snap  # merges on next mount/reboot

# Remove snapshot when done
umount /mnt/snap
lvremove /dev/vg0/snap

Thin provisioning (brief)

Shell
# Create a thin pool
lvcreate -L 50G --thinpool mypool vg0

# Create thin LVs that can over-commit the pool
lvcreate -V 20G --thin -n vol1 vg0/mypool
lvcreate -V 20G --thin -n vol2 vg0/mypool

# Monitor pool usage
lvs -o +data_percent,metadata_percent
Snapshot spaceIf a snapshot's allocated space fills up, it is automatically invalidated. Size snapshots generously or monitor them with lvs -o +snap_percent.
mdadm RAID

Linux software RAID management. Supports RAID levels 0, 1, 4, 5, 6, and 10. The kernel md driver does the actual RAID work; mdadm is the management interface.

RAID is not a backupRAID provides redundancy against drive failure but does NOT protect against accidental deletion, filesystem corruption, ransomware, or simultaneous multi-drive failure. Always maintain separate backups.

Create RAID arrays

Shell
# RAID 1 — mirror (2 drives, survives 1 failure)
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc

# RAID 5 — striped parity (3+ drives, survives 1 failure)
mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sd{b,c,d}

# RAID 6 — dual parity (4+ drives, survives 2 failures)
mdadm --create /dev/md0 --level=6 --raid-devices=4 /dev/sd{b,c,d,e}

# RAID 10 — mirror + stripe (4+ drives)
mdadm --create /dev/md0 --level=10 --raid-devices=4 /dev/sd{b,c,d,e}

# Create with a hot spare
mdadm --create /dev/md0 --level=5 --raid-devices=3 \
      --spare-devices=1 /dev/sd{b,c,d,e}

Monitor RAID status

Shell
mdadm --detail /dev/md0          # full array detail
cat /proc/mdstat                   # quick status of all arrays
mdadm --detail --scan             # all arrays (for mdadm.conf)
watch cat /proc/mdstat             # live rebuild progress

Example /proc/mdstat

Output
Personalities : [raid1] [raid6] [raid5] [raid4]
md0 : active raid5 sdb[0] sdd[2] sdc[1]
      2095104 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]
      # [UUU] = all drives healthy; [U_U] = one failed
      # During rebuild: [===========>.........] recovery = 56.2% (...
unused devices: <none>

Hot spare and drive replacement

Shell
# Add hot spare
mdadm --add /dev/md0 /dev/sde

# Simulate a drive failure (testing)
mdadm --fail /dev/md0 /dev/sdb

# Remove failed drive from array
mdadm --remove /dev/md0 /dev/sdb

# Add replacement drive (rebuild starts automatically)
mdadm --add /dev/md0 /dev/sdf

Persistence — save to mdadm.conf

Shell
# Append array configuration to mdadm.conf
mdadm --detail --scan >> /etc/mdadm/mdadm.conf

# Rebuild initramfs so array assembles on boot
update-initramfs -u              # Debian/Ubuntu
dracut -f                         # RHEL/Fedora

# Stop/start array
mdadm --stop /dev/md0
mdadm --assemble /dev/md0

RAID levels comparison

LevelMin DrivesFault ToleranceUsable CapacityRead PerfWrite PerfBest Use Case
RAID 02None100%ExcellentExcellentScratch space, temp data
RAID 121 drive50%Good (reads mirrored)Write speed of slowestBoot/root, small critical data
RAID 531 drive(N-1)/NGoodModerate (parity overhead)General storage
RAID 642 drives(N-2)/NGoodLower (dual parity)High-value data, large arrays
RAID 1041 per mirror pair50%ExcellentGoodDatabases, high I/O workloads
mkfs Format

Create filesystems on partitions or LVs. Choose ext4 for broad compatibility, XFS for large files and scalability, btrfs for copy-on-write and snapshots.

Create filesystems

Shell
# ext4
mkfs.ext4 /dev/sdb1
mkfs.ext4 -L mydata /dev/sdb1         # with label
mkfs.ext4 -m 1 /dev/sdb1               # 1% reserved blocks (default 5%)
mkfs.ext4 -E lazy_itable_init=0 /dev/sdb1  # initialize all inodes now (slower but safer)

# XFS
mkfs.xfs /dev/sdb1
mkfs.xfs -f /dev/sdb1                  # force overwrite existing filesystem
mkfs.xfs -L mydata /dev/sdb1           # with label

# Btrfs
mkfs.btrfs /dev/sdb1
mkfs.btrfs -L mydata /dev/sdb1         # with label
mkfs.btrfs -d raid1 /dev/sdb1 /dev/sdc1  # btrfs RAID 1 across two devices

# Swap
mkswap /dev/sdb2
swapon /dev/sdb2
swapon -s                              # show active swap
swapoff /dev/sdb2

Filesystem comparison

Featureext4XFSbtrfstmpfs
Max filesystem size1 EiB8 EiB16 EiBRAM limited
Max file size16 TiB8 EiB16 EiBRAM limited
JournalingYes (writeback/ordered/journal)Yes (metadata)CoW (no journal needed)No (in-memory)
SnapshotsNo (use LVM)No (use LVM)Yes (native subvolumes)No
Online resizeGrow onlyGrow onlyGrow & shrinkYes (remount)
Data checksumsNoNoYesNo
StabilityVery stableVery stableMostly stable (avoid RAID 5/6)Stable
Best forGeneral use, boot, VMsLarge files, databases, NFSDesktop, containers, dedupTemp files, /run, /dev/shm
btrfs RAID 5/6btrfs RAID 5 and RAID 6 have known data integrity issues (write hole). Avoid for production data; use mdadm RAID 5/6 under btrfs instead.
mount / umount / fstab Mount

Attach and detach filesystems. /etc/fstab controls what gets mounted at boot. Use UUIDs in fstab — device names like /dev/sdb1 can change between reboots.

Mount and unmount

Shell
mount /dev/sdb1 /mnt/data                   # basic mount
mount -t xfs /dev/sdb1 /mnt/data            # explicit filesystem type
mount -o noatime,nodiratime /dev/sdb1 /mnt/data
mount -o ro /dev/sdb1 /mnt/data             # read-only
mount -o remount,rw /mnt/data               # re-mount read-write

mount | grep sdb                             # show mounts for sdb
findmnt                                      # tree view of all mounts
findmnt /mnt/data                            # info for specific mount

umount /mnt/data                             # unmount by mountpoint
umount /dev/sdb1                             # unmount by device
umount -l /mnt/data                         # lazy umount (detach when idle)
umount -f /mnt/data                         # force (NFS stale mounts)
fuser -mv /mnt/data                         # find what is keeping mount busy

/etc/fstab format

fstab
# <device>                                <mountpoint>  <type>  <options>          <dump> <pass>
UUID=a1b2c3d4-5678-...                   /             ext4    defaults           0      1
UUID=e5f6g7h8-9abc-...                   /boot         ext4    defaults           0      2
UUID=ABCD-1234                           /boot/efi     vfat    umask=0077         0      1
UUID=11223344-...                        /data         xfs     noatime,nodiratime 0      2
/dev/vg0/swap                            none          swap    sw                 0      0

# tmpfs examples
tmpfs                                    /tmp          tmpfs   defaults,size=2G   0      0

fstab fields

FieldValuesNotes
DeviceUUID=…, LABEL=…, /dev/…Prefer UUID — stable across reboots
Mountpointdirectory path, nonenone for swap
Typeext4, xfs, btrfs, vfat, swap, tmpfs, autoauto detects type
Optionscomma-separated (see table below)defaults = rw,suid,dev,exec,auto,nouser,async
dump0 or 11 = include in dump backups; almost always 0
pass0, 1, 21=root (first fsck), 2=others, 0=skip fsck at boot

Common mount options

OptionDescription
noatimeDo not update access time on reads — significant I/O reduction on busy filesystems
nodiratimeDo not update directory access times
relatimeUpdate atime only if older than mtime/ctime — a compromise (default on most systems)
noexecPrevent execution of binaries (good for /tmp, /var)
nosuidIgnore setuid bits — prevents privilege escalation from this mount
roMount read-only
rwMount read-write (default)
discardEnable TRIM for SSDs — tells kernel to issue TRIM on file deletes
nofailBoot succeeds even if this device is missing
lazytimeDelay atime/mtime writes — good compromise for SSDs

Apply fstab changes

Shell
# Test fstab without rebooting
mount -a                              # mount all entries in fstab
mount --fake -a -v                   # dry run (verbose, no actual mount)

# After editing fstab, reload systemd mount units
systemctl daemon-reload

# findmnt tree
findmnt --tree                        # full mount tree
findmnt -t xfs                        # only XFS mounts
df / du Usage

df reports filesystem-level disk usage. du summarizes disk usage of directories and files. Use both to diagnose full disks and inode exhaustion.

df — filesystem usage

Shell
df -h                              # human-readable sizes
df -hT                             # include filesystem type
df -i                              # inode usage (not block usage)
df -hT --exclude-type=tmpfs       # skip tmpfs entries
df /var/log                        # usage of filesystem containing /var/log

du — directory usage

Shell
du -sh /var/log                    # total size of /var/log
du -sh * | sort -h                 # sizes of all items, sorted
du -sh /var/* | sort -rh | head  # top 10 largest under /var
du -h --max-depth=2 /             # two levels deep from root
du -c /var/log/*.gz                # total with grand total at end

# ncdu — interactive TUI (install separately)
ncdu /                             # interactive disk usage browser

Inode exhaustion

A filesystem can run out of inodes while still having free blocks. This causes "No space left on device" even when df -h shows free space.

Shell
# Check inode usage
df -i
# IFree = 0 means inodes exhausted

# Find directories with many files (inode consumers)
find / -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -20

# Find top directories by file count
find /var -xdev -type f | awk -F/ 'OFS="/"{ print $1"/"$2"/"$3 }' | sort | uniq -c | sort -rn
Common inode exhaustion causesMail queues, session files in /var/lib/php/sessions, core dumps, log rotation leftovers, or Docker layers can create millions of small files.
fsck Repair

Check and repair filesystems. fsck is a front-end that calls the appropriate tool (e2fsck for ext4, xfs_repair for XFS, etc.).

Never run fsck on a mounted filesystemRunning fsck on a mounted filesystem will almost certainly corrupt it. Unmount first, or boot from a live/rescue image. The only exception is fsck -n (read-only check) which is generally safe but not recommended.

Basic fsck usage

Shell
umount /dev/sdb1                   # MUST unmount first
fsck /dev/sdb1                     # interactive check (prompts for each issue)
fsck -n /dev/sdb1                  # dry run — report issues, make no changes
fsck -y /dev/sdb1                  # auto-answer yes to all repair questions
fsck -f /dev/sdb1                  # force check even if marked clean
fsck -v /dev/sdb1                  # verbose output

e2fsck — ext4 specific

Shell
e2fsck -f /dev/sdb1               # force full check
e2fsck -f -y /dev/sdb1            # force check, auto-repair
e2fsck -c /dev/sdb1               # check for bad blocks first (slow)

# Force check on next boot (legacy method)
touch /forcefsck                   # triggers fsck on next boot (some distros)
tune2fs -C 1 -c 1 /dev/sdb1      # set mount count to trigger check

# systemd-based force check
systemctl reboot --force          # force fsck if /forcefsck present

xfs_repair — XFS specific

Shell
xfs_repair /dev/sdb1              # repair XFS filesystem
xfs_repair -n /dev/sdb1          # dry run (no modifications)
xfs_repair -L /dev/sdb1          # force log zeroing (last resort — may lose data)

# If xfs_repair says "log needs recovery", mount and unmount first:
mount /dev/sdb1 /mnt/tmp
umount /mnt/tmp
xfs_repair /dev/sdb1
tune2fs / xfs_info / xfs_admin Metadata

Inspect and tune filesystem metadata and parameters. tune2fs for ext2/3/4, xfs_info and xfs_admin for XFS.

tune2fs — ext4 superblock

Shell
tune2fs -l /dev/sdb1               # dump full superblock info
tune2fs -L newlabel /dev/sdb1      # change label
tune2fs -m 1 /dev/sdb1             # reduce reserved blocks from 5% to 1%
tune2fs -e remount-ro /dev/sdb1    # remount ro on error instead of panicking
tune2fs -i 0 -c 0 /dev/sdb1       # disable periodic fsck (not recommended)
tune2fs -O has_journal /dev/sdb1   # add journaling to ext2

Key tune2fs -l output fields

FieldMeaning
Filesystem stateclean = unmounted cleanly; not clean = needs fsck
Mount countTimes mounted since last fsck
Maximum mount countForce fsck after N mounts (-1 = disabled)
Reserved block countBlocks reserved for root (default 5% of total)
Last checkedDate of last fsck
Inode count / Free inodesTotal and available inodes

xfs_info — XFS metadata

Shell
xfs_info /mnt/data                 # requires mounted filesystem
xfs_info /dev/sdb1                 # also works on device directly

xfs_admin — XFS tuning

Shell
xfs_admin -l /dev/sdb1             # show label
xfs_admin -L newlabel /dev/sdb1   # set label (unmounted)
xfs_admin -U generate /dev/sdb1    # generate new UUID
smartctl Health

S.M.A.R.T. (Self-Monitoring, Analysis, and Reporting Technology) reports drive health metrics from the drive firmware itself. Essential for proactive disk failure detection.

Basic health checks

Shell
smartctl -a /dev/sda               # full SMART report (all attributes)
smartctl -H /dev/sda               # quick health summary
smartctl -i /dev/sda               # drive identity (model, firmware, serial)
smartctl -A /dev/sda               # SMART attribute values only

# NVMe drives
smartctl -a /dev/nvme0             # NVMe health report

Example output — smartctl -H

Output
=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
# If result is FAILED — back up data immediately and replace drive

Run self-tests

Shell
smartctl -t short /dev/sda         # short test (~2 min, runs in background)
smartctl -t long /dev/sda          # long test (~hours, checks all sectors)
smartctl -t conveyance /dev/sda    # conveyance test (HDD only, post-shipping)

# Check test results (look for status "Completed without error")
smartctl -l selftest /dev/sda
smartctl -a /dev/sda | grep -A3 "Self-test execution"

Key SMART attributes

IDAttributeWhat it meansWarning threshold
5Reallocated_Sector_CtSectors remapped due to read errors. Increasing count = drive surface degrading.Any non-zero and increasing value
187Reported_UncorrectUncorrectable errors reported to OS. Serious — indicates data loss risk.Any non-zero value
188Command_TimeoutCommands that timed out. May indicate cable or power issues.Increasing values
197Current_Pending_SectorSectors waiting to be reallocated. Drive is attempting to read but failing.Any non-zero value
198Offline_UncorrectableSectors that could not be corrected during offline scan.Any non-zero value
9Power_On_HoursTotal hours of operation. Context for other wear metrics.Depends on drive model
190/194Temperature_CelsiusDrive temperature. HDDs: <55°C. SSDs: <70°C.Sustained >60°C (HDD)
177Wear_Leveling_CountSSD wear leveling health (100=new, 0=worn out)Below 10
231SSD_Life_LeftSSD estimated remaining life percentageBelow 10%

smartd — background monitoring daemon

Shell
# Enable and start smartd
systemctl enable --now smartd

# /etc/smartd.conf — monitor all drives and email on failure
DEVICESCAN -H -l error -l selftest -f -s (S/../.././02|L/../../6/03) -m root

# Test smartd email configuration
smartd -M test -m root
SMART is not infallibleSome drives fail without SMART warnings. Some show warnings for months without failing. Use SMART as one signal alongside regular backups and monitoring.
Practical Recipes Howto

End-to-end workflows for common storage tasks.

Add a new disk end-to-end (partition → LVM → mkfs → mount → fstab)

Shell
# 1. Identify the new disk
lsblk -d -o NAME,SIZE,MODEL

# 2. Partition the disk (GPT)
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary ext4 1MiB 100%
parted /dev/sdb set 1 lvm on

# 3. Create LVM structures
pvcreate /dev/sdb1
vgcreate vg_data /dev/sdb1
lvcreate -l 100%FREE -n data vg_data

# 4. Format the logical volume
mkfs.ext4 -L data /dev/vg_data/data

# 5. Create mount point and mount
mkdir -p /mnt/data
mount /dev/vg_data/data /mnt/data

# 6. Add to fstab (use UUID for reliability)
blkid -o value -s UUID /dev/vg_data/data
# Add to /etc/fstab:
# UUID=<uuid>  /mnt/data  ext4  defaults,noatime  0  2

# 7. Test fstab entry
mount -a
df -h /mnt/data

Extend an LVM volume online

Shell
# Check current state
vgs                                       # how much VG free space?
lvs /dev/vg_data/data

# If VG has free space — extend LV directly
lvextend -L +20G -r /dev/vg_data/data   # -r resizes filesystem too

# If VG is full — add a new disk first
pvcreate /dev/sdc
vgextend vg_data /dev/sdc
lvextend -l +100%FREE -r /dev/vg_data/data

# Verify
df -h /mnt/data

Replace a failed RAID 1 drive

Shell
# 1. Check current status
cat /proc/mdstat
mdadm --detail /dev/md0

# 2. Mark the failed drive as failed (if not already)
mdadm --fail /dev/md0 /dev/sdb

# 3. Remove it from the array
mdadm --remove /dev/md0 /dev/sdb

# 4. Physically replace the drive, then partition the new drive
# (match partition layout of surviving drive)
sfdisk -d /dev/sdc | sfdisk /dev/sdb    # clone partition table from good drive

# 5. Add new drive to array (rebuild starts automatically)
mdadm --add /dev/md0 /dev/sdb1

# 6. Monitor rebuild progress
watch cat /proc/mdstat

Find what's using all inodes

Shell
# Step 1: confirm inode exhaustion
df -i
# Look for filesystem where IUse% = 100%

# Step 2: find directory with most files
find / -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -20

# Step 3: investigate top offender (e.g. /var/spool/postfix/deferred)
ls /var/spool/postfix/deferred | wc -l

# Step 4: clean up (example: clear old PHP sessions)
find /var/lib/php/sessions -type f -mtime +1 -delete

# Verify recovery
df -i
Cheat Sheet Reference

lsblk / blkid

lsblk -f — devices with FS type
lsblk -d -o NAME,SIZE,ROTA,MODEL
blkid -o value -s UUID /dev/sdb1
findmnt --tree

fdisk / parted

fdisk -l — list all partitions
fdisk /dev/sdb — interactive MBR
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary ext4 1MiB 100%

LVM quick reference

pvcreate /dev/sdb1
vgcreate vg0 /dev/sdb1
lvcreate -L 10G -n data vg0
lvextend -L +5G -r /dev/vg0/data
lvcreate -L 1G -s -n snap /dev/vg0/data

mdadm RAID

mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sd{b,c}
mdadm --detail /dev/md0
cat /proc/mdstat
mdadm --fail /dev/md0 /dev/sdb
mdadm --add /dev/md0 /dev/sde

mkfs & swap

mkfs.ext4 -L label /dev/sdb1
mkfs.xfs -f /dev/sdb1
mkfs.btrfs /dev/sdb1
mkswap /dev/sdb2 && swapon /dev/sdb2

mount / fstab

mount -o noatime /dev/sdb1 /mnt/data
umount -l /mnt/data
mount -a — test fstab
systemctl daemon-reload after fstab edit
fuser -mv /mnt/data — who is using mount

df / du

df -hT — usage with FS type
df -i — inode usage
du -sh * | sort -rh | head
ncdu / — interactive browser

fsck & repair

fsck -f -y /dev/sdb1 — force repair
e2fsck -f /dev/sdb1 — ext4
xfs_repair -n /dev/sdb1 — XFS dry run
Unmount before fsck!

tune2fs / xfs

tune2fs -l /dev/sdb1 — superblock
tune2fs -m 1 /dev/sdb1 — reduce reserved
xfs_info /mnt/data
xfs_admin -L newlabel /dev/sdb1

smartctl

smartctl -H /dev/sda — health check
smartctl -a /dev/sda — full report
smartctl -t short /dev/sda — short test
smartctl -t long /dev/sda — long test
Watch: Reallocated_Sector_Ct, Pending_Sector_Count