Disks, filesystems and mounts

lsblk, findmnt, fstab and full disks.

Beginner16 min · lesson 22 of 29

A server keeps its files on one or more disks, but you never work with a disk directly: you see a single directory tree that starts at /. This lesson shows how to find which disks and filesystems a server has and where each is attached, how to add a filesystem that is mounted at every boot without putting the boot or its services at risk, and what to check, in order, when the disk is full, one of the most common causes of an outage.

Disks, partitions and filesystems

Three layers are involved. A block device is a disk as the kernel presents it: a long row of numbered blocks that can be read and written. A partition is a slice of a disk that behaves like a disk of its own. A filesystem is the structure written onto a device that turns its blocks into files and directories with names, owners and permissions. lsblk -f shows all three:

deploy@web01 · Ubuntu 26.04 LTS
$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS vda ├─vda1 ext4 1.0 cloudimg-rootfs daaf8301-e652-48d8-ae35-1c7fc60c3182 18G 19% / ├─vda13 ext4 1.0 BOOT e57a54d1-fbe4-4b61-93d1-e8a9516127ff 606.8M 25% /boot └─vda15 vfat FAT32 UEFI 93C3-632E 91M 7% /boot/efi vdb iso9660 cidata 2026-09-27-01-26-30-63 0 100% /mnt/lima-cidata

vda is the lab machine's virtual disk (virtio, the disk driver most virtual machines use); physical servers and many clouds show sda or nvme0n1. The tree lines show its three partitions. FSTYPE is the filesystem on each: ext4 for / and /boot, vfat for /boot/efi, the partition the firmware reads at power-on. LABEL and UUID are names stored inside the filesystem, FSAVAIL and FSUSE% show free space, and MOUNTPOINTS where each filesystem appears. vdb (cidata) is a small disc the virtualisation tool attaches with first-boot settings; a real server does not have it.

findmnt answers the reverse question: which filesystem holds this directory? Ubuntu formats its root filesystem as ext4, while RHEL and Rocky Linux use XFS:

deploy@web01 · Ubuntu 26.04 LTS
$ findmnt /
TARGET SOURCE FSTYPE OPTIONS / /dev/vda1 ext4 rw,relatime,discard,errors=remount-ro,commit=30
deploy@rocky10 · Rocky Linux 10.2
$ findmnt /
TARGET SOURCE FSTYPE OPTIONS / /dev/vda3 xfs rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota

Both are mature journaling filesystems: they record changes to their own bookkeeping (the metadata) in a journal before making them, so a crash does not leave the structure half-updated. Day to day the difference is mainly the tools (e2fsck and resize2fs for ext4, xfs_repair and xfs_growfs for XFS). OPTIONS lists the mount options in force; rw means read-write.

One tree, built from mounts

Mounting attaches a filesystem to a directory, its mount point, so that the directory shows the filesystem's contents. The root filesystem is mounted at / first and every other filesystem is attached somewhere below it. df -hT lists what is mounted, with sizes in K, M and G (-h) and each filesystem's type (-T):

deploy@web01 · Ubuntu 26.04 LTS
$ df -hT
Filesystem Type Size Used Avail Use% Mounted on tmpfs tmpfs 780M 1.1M 779M 1% /run /dev/vda1 ext4 23G 4.2G 19G 19% / tmpfs tmpfs 2.0G 100K 2.0G 1% /dev/shm efivarfs efivarfs 56K 1.5K 55K 3% /sys/firmware/efi/efivars tmpfs tmpfs 2.0G 144K 2.0G 1% /tmp /dev/vda13 ext4 891M 222M 607M 27% /boot /dev/vda15 vfat 98M 6.5M 91M 7% /boot/efi none tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-networkd.service … none tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-resolved.service none tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service

Only three of these rows are disk partitions. The tmpfs rows are filesystems kept in RAM, empty at every boot: /run, /dev/shm, /tmp on Ubuntu 26.04, and small ones under /run/credentials/ in which systemd hands settings or secrets to a service (the rows left out are more of these). efivarfs exposes the firmware's variables. To see real storage only, leave out the in-memory types:

deploy@web01 · Ubuntu 26.04 LTS
$ df -hT -x tmpfs -x efivarfs
Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 ext4 23G 4.2G 19G 19% / /dev/vda13 ext4 891M 222M 607M 27% /boot /dev/vda15 vfat 98M 6.5M 91M 7% /boot/efi /dev/vdb iso9660 54M 54M 0 100% /mnt/lima-cidata

/dev/vdb is the virtualisation tool's settings disc again. Use% is the column to watch: a filesystem at 100% refuses new data from ordinary programs.

Mount options change how the kernel treats a whole filesystem. nosuid ignores set-user-ID and set-group-ID bits and file capabilities, nodev ignores device files, and noexec refuses to run programs stored there. On Ubuntu 26.04, /tmp gets the first two:

deploy@web01 · Ubuntu 26.04 LTS
$ findmnt /tmp
TARGET SOURCE FSTYPE OPTIONS /tmp tmpfs tmpfs rw,nosuid,nodev,size=1994676k,nr_inodes=1048576,inode64,usrquota

An ordinary user cannot create a set-user-ID root file, so nosuid here guards against a SUID program left or planted in this world-writable place by a privileged process or an intruder who briefly had root ("SUID, SGID and the sticky bit" explains more). size= caps /tmp at half the memory. RHEL 10 has no tmpfs on /tmp, and the hardening course applies these options to other directories.

Adding a filesystem

A new disk appears as a new, empty block device, such as /dev/sdb or /dev/nvme1n1. The lab has no spare disk, so it makes one from a file: a loop device is a block device whose blocks live in an ordinary file, and from then on the commands are the same as for a real disk.

deploy@web01 · Ubuntu 26.04 LTS
$ mkdir /var/tmp/ess-storage truncate -s 64M /var/tmp/ess-storage/disk.img ls -lsh /var/tmp/ess-storage/disk.img
0 -rw-rw-r-- 1 deploy deploy 64M Sep 27 08:14 /var/tmp/ess-storage/disk.img
$ sudo losetup --find --show /var/tmp/ess-storage/disk.img
/dev/loop0
$ lsblk -f /dev/loop0
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS loop0

truncate created a sparse file: the 0 at the start of the ls -s line is the space really allocated, because blocks are only taken as data is written. losetup --find --show attached the file to the first free loop device and printed its name (yours may have another number), which has no filesystem yet. mkfs.ext4 writes a new, empty ext4 filesystem onto a device, and -L gives it a label:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo mkfs.ext4 -L ess-data /dev/loop0
mke2fs 1.47.2 (1-Jan-2025) Discarding device blocks: 0/16384 done Creating filesystem with 16384 4k blocks and 16384 inodes Allocating group tables: 0/1 done Writing inode tables: 0/1 done Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: 0/1 done

The output gives the size in 4 KiB blocks, the number of inodes (an inode is the record of one file's owner, permissions and data location) and the journal size. Formatting destroys what the device held, so check the name with lsblk -f first. Now create a mount point, mount the filesystem and look at it:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo mkdir /mnt/ess-data sudo mount /dev/loop0 /mnt/ess-data findmnt /mnt/ess-data
TARGET SOURCE FSTYPE OPTIONS /mnt/ess-data /dev/loop0 ext4 rw,relatime
$ df -h /mnt/ess-data
Filesystem Size Used Avail Use% Mounted on /dev/loop0 56M 152K 52M 1% /mnt/ess-data

The filesystem holds 56M rather than 64M because the journal and the inode tables take space. Avail is also smaller than Size minus Used: ext4 reserves 5% of the blocks for root, so that services running as root keep working after ordinary users have filled the disk. The top directory of a new filesystem belongs to root, so hand it to the account that will use it:

deploy@web01 · Ubuntu 26.04 LTS
$ touch /mnt/ess-data/test
touch: cannot touch '/mnt/ess-data/test': Permission denied
$ sudo chown deploy: /mnt/ess-data touch /mnt/ess-data/test ls -l /mnt/ess-data
total 16 drwx------ 2 root root 16384 Sep 27 08:14 lost+found -rw-rw-r-- 1 deploy deploy 0 Sep 27 08:14 test

In sudo chown deploy: /mnt/ess-data, the colon with no group after it sets the group to the user's login group. lost+found is where e2fsck puts pieces of files it recovers after a crash.

Mounting at boot: /etc/fstab

A mount command lasts until the next reboot. Filesystems that must come back at boot are listed in /etc/fstab, one per line. systemd reads the file early at boot, and again whenever it is reloaded, and turns each line into a mount unit. On the Ubuntu cloud image it contains:

deploy@web01 · Ubuntu 26.04 LTS
$ cat /etc/fstab
LABEL=cloudimg-rootfs / ext4 discard,commit=30,errors=remount-ro 0 1 LABEL=BOOT /boot ext4 defaults 0 2 LABEL=UEFI /boot/efi vfat umask=0077 0 1

Each line has six fields: what to mount, where, the filesystem type, the mount options, a field for the old dump backup tool that is nearly always 0, and the order in which fsck checks filesystems at boot (1 for the root filesystem, 2 for the others, 0 for never). The first field names each filesystem by its label rather than as /dev/vda1: the kernel names devices in the order it finds disks, so names can change, while a label or UUID moves with the filesystem. RHEL uses UUIDs:

deploy@rocky10 · Rocky Linux 10.2
$ cat /etc/fstab
UUID=adbc700e-905a-4aa3-90a2-084cd25fcc12 / xfs defaults 0 1 UUID=331e63bc-2fab-4a52-9315-a16bdf50205e /boot xfs defaults 0 0 UUID=38C7-E39B /boot/efi vfat defaults,umask=0077,shortname=winnt 0 0

A mistake in /etc/fstab is one of the few configuration errors that can stop a server from booting. systemd waits up to 90 seconds for each listed device, and when a filesystem the boot requires cannot be mounted, local-fs.target fails and systemd starts emergency mode, a root shell on the console. Without console access, the machine is then out of reach. nofail makes a filesystem wanted rather than required, so the boot carries on without it. Use it for data disks the system can boot without, but together with the service setting in the next section: on its own it moves the problem to the services that use the disk.

The safe routine is to find the filesystem's UUID, add the line, and check the file before anything uses it. The lab works on a copy of /etc/fstab, so nothing it does can affect the next boot:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo blkid /dev/loop0
/dev/loop0: LABEL="ess-data" UUID="925035f0-7e01-4e7d-89fc-0c8860ab6919" BLOCK_SIZE="4096" TYPE="ext4"
$ cp /etc/fstab /var/tmp/ess-storage/fstab

Here are the last two lines of the copy after adding the new line with an editor (fields can be separated by any spaces or tabs):

deploy@web01 · Ubuntu 26.04 LTS
$ tail -n 2 /var/tmp/ess-storage/fstab
LABEL=UEFI /boot/efi vfat umask=0077 0 1 UUID=925035f0-7e01-4e7d-89fc-0c8860ab6919 /mnt/ess-data ext4 defaults,nofail 0 2

findmnt --verify reads an fstab file and checks every line: that the source can be found, that the mount point exists and that the type is one the kernel supports. --tab-file points it at a file other than /etc/fstab:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo findmnt --verify --tab-file /var/tmp/ess-storage/fstab
Success, no errors or warnings detected

A UUID with one character wrong, on a line without nofail, is exactly the mistake that stops a boot, and the check catches it:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo findmnt --verify --tab-file /var/tmp/ess-storage/fstab.bad-uuid
0 parse errors, 1 error, 0 warnings /mnt/ess-data [E] unreachable on boot required source: UUID=925035f0-7e01-4e7d-89fc-0c8860ab691a

"Unreachable on boot required source" means the boot would wait for a device that will never appear. Last, prove that the line works by mounting from it. mount --fstab reads the copy, and given only a mount point it takes everything else from the matching line:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo umount /mnt/ess-data sudo mount --fstab /var/tmp/ess-storage/fstab /mnt/ess-data findmnt /mnt/ess-data
TARGET SOURCE FSTYPE OPTIONS /mnt/ess-data /dev/loop0 ext4 rw,relatime

On a real server the same routine runs on /etc/fstab itself: edit it with sudoedit /etc/fstab, run sudo findmnt --verify, run sudo systemctl daemon-reload so that systemd rebuilds its mount units from the file, then sudo mount /mnt/data (or sudo mount -a for every line) to prove the line before the next reboot tests it for you.

When a nofail disk is missing

With nofail, a missing disk no longer stops the boot, but the services that use it still start, and the mount point is then an empty directory on the root filesystem. A program that runs as root, or finds its directory in place, starts a fresh data set there, fills /, and leaves two copies that disagree once the disk is back. Here is a stand-in database, a service that appends the date to a file under /mnt/ess-data/db:

/etc/systemd/system/ess-storage-db.service
[Unit]
Description=Stand-in database that keeps its data on /mnt/ess-data
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'mkdir -p /mnt/ess-data/db && date >> /mnt/ess-data/db/data'

The mount unit systemd makes from an fstab line is named after the path, here mnt-ess\x2ddata.mount (\x2d stands for -). The lab created that unit directly under /run/systemd/system, to leave the real /etc/fstab alone, from the line LABEL=ess-data /mnt/ess-data ext4 defaults,nofail 0 2; to try it yourself, add that line to /etc/fstab, run sudo systemctl daemon-reload, and remove it afterwards. Now the disk disappears and the service starts:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo umount /mnt/ess-data sudo losetup -d /dev/loop0
$ sudo systemctl start ess-storage-db findmnt -T /mnt/ess-data/db
TARGET SOURCE FSTYPE OPTIONS / /dev/vda1 ext4 rw,relatime,discard,errors=remount-ro,commit=30

findmnt -T names the filesystem that holds a path: the data went to /dev/vda1, the root filesystem. Remove it, and tie the service to the mount with a drop-in (sudo systemctl edit ess-storage-db opens an editor for it):

deploy@web01 · Ubuntu 26.04 LTS
$ sudo rm -r /mnt/ess-data/db
$ systemctl cat ess-storage-db
# /etc/systemd/system/ess-storage-db.service [Unit] Description=Stand-in database that keeps its data on /mnt/ess-data [Service] Type=oneshot ExecStart=/bin/sh -c 'mkdir -p /mnt/ess-data/db && date >> /mnt/ess-data/db/data' # /etc/systemd/system/ess-storage-db.service.d/override.conf [Unit] RequiresMountsFor=/mnt/ess-data

RequiresMountsFor= makes the service require, and start after, every mount unit needed to reach that path. With the disk still missing, the service now refuses to start:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo systemctl start ess-storage-db
A dependency job for ess-storage-db.service failed. See 'journalctl -xe' for details.
$ systemctl status /mnt/ess-data
○ mnt-ess\x2ddata.mount - /mnt/ess-data (the LABEL=ess-data line of /etc/fstab) Loaded: loaded (/run/systemd/system/mnt-ess\x2ddata.mount; static) Active: inactive (dead) Where: /mnt/ess-data What: /dev/disk/by-label/ess-data … Sep 27 08:15:54 web01 systemd[1]: Dependency failed for mnt-ess\x2ddata.mount - /mnt/ess-data (the LABEL=ess-data line of /etc/fstab). Sep 27 08:15:54 web01 systemd[1]: mnt-ess\x2ddata.mount: Job mnt-ess\x2ddata.mount/start failed with result 'dependency'.

systemctl status also accepts a mount point instead of a unit name. The start waited 90 seconds, systemd's default time for a device to appear, then the mount failed and the service with it, and nothing was written. When the disk is back, starting the service mounts the filesystem first:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo losetup --find --show /var/tmp/ess-storage/disk.img sudo systemctl start ess-storage-db findmnt /mnt/ess-data ls /mnt/ess-data/db
/dev/loop0 TARGET SOURCE FSTYPE OPTIONS /mnt/ess-data /dev/loop0 ext4 rw,relatime data
$ sudo rm -r /mnt/ess-data/db

So the rule is nofail on the disk and RequiresMountsFor= on every service that keeps data on it.

When the disk is full

When a filesystem fills up, writes fail with No space left on device. On the lab filesystem a stand-in application, a small service running as deploy, writes its log to /mnt/ess-data/logs/app.log, and the log has filled the filesystem:

deploy@web01 · Ubuntu 26.04 LTS
$ df -h /mnt/ess-data
Filesystem Size Used Avail Use% Mounted on /dev/loop0 56M 52M 0 100% /mnt/ess-data
$ cp /etc/services /mnt/ess-data/
cp: error writing '/mnt/ess-data/services': No space left on device

Work down from the filesystem to the directory. du adds up the files under a directory: -x keeps it on one filesystem, -h prints readable sizes and --max-depth=1 gives one line per subdirectory:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo du -xh --max-depth=1 /mnt/ess-data
52M /mnt/ess-data/logs 16K /mnt/ess-data/lost+found 52M /mnt/ess-data
$ ls -lh /mnt/ess-data/logs
total 52M -rw-r--r-- 1 deploy deploy 52M Sep 27 08:15 app.log

The log is the culprit. Deleting it looks like the fix, but the space does not come back:

deploy@web01 · Ubuntu 26.04 LTS
$ rm /mnt/ess-data/logs/app.log df -h /mnt/ess-data
Filesystem Size Used Avail Use% Mounted on /dev/loop0 56M 52M 0 100% /mnt/ess-data
$ sudo du -sh /mnt/ess-data
24K /mnt/ess-data

df still reports 100% while du finds 24K. A file's space is released only when its last name is removed and no process has it open, and the application still has the log open. lsof +aL1 lists open files with no name left (a link count below 1) on the filesystem you give it:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo lsof +aL1 /mnt/ess-data
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME app.sh 1247283 deploy 11w REG 7,0 53821440 0 14 /mnt/ess-data/logs/app.log (deleted)

The process app.sh, running as deploy, holds the file on descriptor 11, open for writing (11w). SIZE/OFF is the 53 MB it still occupies and NLINK 0 means no name points to it. Restarting the service makes it let go. If the restart has to wait, empty the file through the process's own descriptor: /proc/PID/fd/11 still leads to the open file although it has no name, and pgrep -x app.sh supplies the PID:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo truncate -s 0 /proc/$(pgrep -x app.sh)/fd/11 df -h /mnt/ess-data
Filesystem Size Used Avail Use% Mounted on /dev/loop0 56M 156K 52M 1% /mnt/ess-data

The space is back at once, but the process still holds a deleted file. Restart it when you can, and it opens a new log:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo systemctl restart ess-storage-app
$ df -h /mnt/ess-data
Filesystem Size Used Avail Use% Mounted on /dev/loop0 56M 160K 52M 1% /mnt/ess-data

Better still, never delete a log that a program has open: truncate -s 0 FILE empties it in place, and logrotate rotates logs on a schedule (its copytruncate option loses the lines written between the copy and the truncation). Emptying in place works cleanly only for a program that writes in append mode, as this one does; one that keeps its own write position carries on at the old offset, and ls -l still shows the old size.

On a real server the search starts at /, where -x matters most: without it du would also wander into /proc, /run, /tmp and every other filesystem mounted below the root. sort -h orders the readable sizes and tail keeps the largest:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo du -xh --max-depth=1 / | sort -h | tail -n 5
496K /root 7.5M /etc 1.1G /var 3.2G /usr 4.3G /
/dev/mapper in df: LVM
Servers built with the Ubuntu Server or RHEL installer usually use LVM, which pools disks into a volume group and cuts logical volumes from it; df then shows /dev/mapper/ubuntu--vg-ubuntu--lv or /dev/mapper/rhel-root. Ubuntu's default layout leaves part of a larger volume group unallocated, so before deleting anything on a full /, check sudo vgs: space under VFree can be added to the volume. Growing a volume is covered in the Linux internals course.

There is a second way to run out of space. ext4 creates a fixed number of inodes when the filesystem is made (16384 on this small one), and a program that writes huge numbers of tiny files, such as a cache, can use them all while blocks remain. df -i counts inodes instead of blocks:

deploy@web01 · Ubuntu 26.04 LTS
$ df -i /mnt/ess-data
Filesystem Inodes IUsed IFree IUse% Mounted on /dev/loop0 16384 16 16368 1% /mnt/ess-data
$ mkdir /mnt/ess-data/cache cd /mnt/ess-data/cache for i in $(seq 20000); do touch "f$i" || break; done
touch: cannot touch 'f16368': No space left on device
$ df -h /mnt/ess-data df -i /mnt/ess-data
Filesystem Size Used Avail Use% Mounted on /dev/loop0 56M 560K 51M 2% /mnt/ess-data Filesystem Inodes IUsed IFree IUse% Mounted on /dev/loop0 16384 16384 0 100% /mnt/ess-data

The for loop runs touch for f1, f2 and so on up to f20000, and || break stopped it at the first failure: No space left on device, with 51M still free according to df -h. IUse% 100% is the real reason. XFS creates inodes as it needs them, which makes it much less prone to this.

No space left on device: which kind?
A write fails with No space left on device
run df -h and df -i on that filesystem
df -h full, du agrees
Something large is there
du -xh --max-depth=1, then remove or move it
df -h full, du far lower
A deleted file is still open
lsof +aL1, then restart that process
df -h has room, df -i full
Out of inodes
find the directory with too many small files

To detach a filesystem, unmount it. That fails while any process still uses it, and fuser -vm names the processes:

deploy@web01 · Ubuntu 26.04 LTS
$ sudo umount /mnt/ess-data
umount: /mnt/ess-data: target is busy.
$ sudo fuser -vm /mnt/ess-data
USER PID ACCESS COMMAND /mnt/ess-data: root kernel mount /mnt/ess-data deploy 1247556 F.... app.sh
$ sudo systemctl stop ess-storage-app sudo umount /mnt/ess-data sudo losetup -d /dev/loop0 losetup -a

In the ACCESS column, F is a file open for writing and c would be a process whose current directory is inside the mount, which is the usual culprit when the process is your own shell. Stop or move the process, then unmount; losetup -d detaches the loop device, and the empty losetup -a confirms nothing is attached.

Try this

Build the loop filesystem from this lesson, mount it, give it to your account and put a small script on it: printf '#!/bin/sh\necho hello from the new disk\n' > /mnt/ess-data/hello.sh, then chmod +x /mnt/ess-data/hello.sh. Run it, remount with sudo mount -o remount,noexec /mnt/ess-data and run /mnt/ess-data/hello.sh again: it fails with Permission denied, and findmnt -no OPTIONS /mnt/ess-data shows why. Now run sh /mnt/ess-data/hello.sh: it prints its message, because noexec stops the kernel from executing files there but not a program that reads the file as its input. Remount with exec, then clean up with sudo umount /mnt/ess-data, sudo losetup -d /dev/loop0 and rm -r /var/tmp/ess-storage (and remove any line you added to /etc/fstab).

Takeaway

Check every change to /etc/fstab with findmnt --verify, and give a data disk nofail only together with RequiresMountsFor= on the services that use it. When a disk fills up, compare df with du: if they disagree, a deleted file is still open, and lsof +aL1 names the process to restart.

Quick check
01df -h shows / at 100%, but sudo du -xh --max-depth=1 / adds up to far less, and a colleague deleted a 20 GB log an hour ago. What do you do next?
Incorrect — A mounted, healthy filesystem can show exactly this difference. Nothing is damaged, and e2fsck must not be run on a mounted filesystem.
Correct — The space stays allocated while any process has the file open; restarting the process closes it and frees the blocks.
Incorrect — du counts small files too. The missing space belongs to a file that no longer has a name, so du cannot see it at all.
Incorrect — The commit interval delays writing changes to disk; it does not keep deleted space for an hour. An open file does.
02You add a data disk to /etc/fstab by UUID with the options defaults, and forget about it. Months later the disk is detached and the server reboots. What happens?
Incorrect — systemd does create missing mount points, but the device itself is missing, and without nofail the mount is required.
Incorrect — systemd-fstab-generator turns /etc/fstab into mount units at every boot, so each line takes part in the boot.
Incorrect — A UUID names one specific filesystem. If it is not present, nothing else is mounted in its place.
Correct — Without nofail the mount is required; after the device timeout local-fs.target fails, and its OnFailure= starts emergency.target.
03An application that stores sessions as small files fails with "No space left on device", yet df -h shows its filesystem at 40% used. What is the likely cause?
Correct — Every file needs an inode, and ext4 has a fixed number of them, so many tiny files can exhaust them while blocks remain free.
Incorrect — The reserve only matters once the ordinary blocks are used up, and df -h would then show 100%.
Incorrect — ext4 directories can hold millions of entries. The error comes from the filesystem, and df -i shows why.
Incorrect — A slow disk makes writes wait; it does not return "No space left on device".

Related