Mounting: Explanation & Insights

Attaching a filesystem from a disk, partition, or network share to a directory, making its contents accessible within Linux's single file tree.

What It Is

Mounting is the act of attaching a filesystem to a place in Linux's directory tree, so that the files it holds suddenly appear under some folder you can cd into. That place is called a mount point, and it's just an ordinary directory — /data, /mnt/backup, /boot/efi, whatever you like. Before you mount, the directory is empty (or near enough). After you mount, the same path leads straight into the contents of the device. Nothing physical moves; you've simply told the kernel, "when someone walks into this folder, route them onto that filesystem instead."

Here is the idea that trips up everyone arriving from Windows, and it's worth getting clear on before anything else: Linux has no drive letters. There is no C:, no D:, no E:. There is exactly one tree, and it begins at the root directory, written /. Every disk, every partition, every USB stick, every NFS share, every LVM volume you ever touch gets grafted somewhere onto that one tree. Your root filesystem lives at /. Plug in a second disk and you might mount it at /data — now /data is a doorway into that disk, and /data/projects/report.txt is a file on it, indistinguishable in everyday use from a file on the root disk. The whole machine, no matter how many disks it has, presents as a single seamless hierarchy. That unification is one of Unix's quietly brilliant decisions, and it's why "everything is a file" actually scales: there's only ever one namespace to reason about.

This page goes the whole way. We'll cover mount points and the mount / umount commands, dissect every column of /etc/fstab, list what's mounted with findmnt, walk through the mount options that matter on a server, untangle the "target is busy" error and the lazy unmount, explain bind mounts, and end with a word on the mount namespaces that make containers possible. Two things in particular are muddy in most tutorials, and we'll nail both: why you should identify a filesystem by its UUID and never by /dev/sdX, and where your files "vanish to" when you mount over a directory that already had something in it.

Why It Matters

Mounting sits on the critical path of booting. The very first filesystem Linux mounts is the root filesystem at /; if that fails, the machine doesn't come up. Right after it, the kernel reads /etc/fstab and mounts everything else listed there. Get a single line in that file wrong — a typo, a device name that drifted, a network share that isn't reachable yet — and you can land in an emergency shell with a blinking cursor and a server that won't finish booting. This is not a rare disaster; it's one of the most common ways a perfectly healthy box ends up "down." The disks are fine. The data is fine. The mount instructions were wrong, and Linux took them at their word.

So mounting is worth understanding not because it's hard — the happy path is one command — but because the failure modes are quiet, confusing, and tend to strike at boot, which is the worst possible time. The two classic ones, which this page exists to inoculate you against, are an /etc/fstab that points at a device name which has since reshuffled, and a mount that silently hides files you were certain were right there a moment ago. Both look like data loss. Neither is. Once you've seen each once, you never fall for it again — so let's get you there without the 3 a.m. version.

How Mounting Works

The Mount Point Is Just a Directory

There's no special kind of folder you have to create. A mount point is any directory; mounting replaces what you see when you enter it with the root of the attached filesystem. Convention puts permanent mounts under / directly (/data, /srv, /home when it's a separate disk), temporary or removable ones under /mnt and /media, and the EFI partition at /boot/efi. But these are conventions, not rules — the kernel will happily mount a disk onto /var/log or /opt/app if you ask it to.

The basic move is two steps: make a directory, then mount onto it.

mkdir /data
mount /dev/sdb1 /data

After the second line, /data is the second disk. ls /data lists its files. Write a file there and it lands on sdb1, not on the root disk. To detach it again:

umount /data

You can name either the mount point (umount /data) or the device (umount /dev/sdb1) — both work. After unmounting, /data is back to being an ordinary, empty directory on the root filesystem.

What the Kernel Actually Tracks

Under the hood the kernel keeps a table of every active mount: which source (a block device, a network address, a virtual source) is attached to which mount point, with which filesystem type and which options. You can read that table directly — it's exposed as a file, of course, at /proc/mounts (and /proc/self/mountinfo for the richer version). When you run mount with no arguments, you're really just getting a human-friendly dump of that kernel table. The same data, one layer up.

That's the reveal worth pausing on: there is no daemon managing mounts, no background service. A mount is a live entry in a kernel data structure, created by one syscall (mount(2)) and torn down by another (umount(2)). The mount command is a thin wrapper that figures out the right arguments and makes the syscall. Everything you do to storage in Linux bottoms out in the kernel keeping a list.

Identify Filesystems by UUID, Not by /dev/sdX

This is the single most important habit on this page, so it gets its own section. Device names like /dev/sda1 are not stable. Linux assigns them in the order it discovers disks during boot, and that order is not guaranteed. Add a second disk, swap a SATA cable to a different port, plug in a USB drive that happens to enumerate first, let the BIOS probe the controllers in a different sequence after a firmware update — and the disk that was /dev/sdb yesterday is /dev/sdc today. The hardware didn't change. The name did.

Now imagine your /etc/fstab says /dev/sdb1 /data ext4 .... After the reshuffle, /dev/sdb1 is a different disk — maybe your swap partition, maybe nothing at all. At best the mount fails and /data is empty; at worst the boot hangs waiting for a device that, under that name, no longer holds what fstab expects. A box that booted cleanly for two years suddenly drops to an emergency shell, and the cause is a name that drifted by one letter.

Warning

An /etc/fstab pointing at /dev/sdb1 is a time bomb. The day a disk is added, a cable is moved, or the probe order changes, /dev/sdb1 becomes a different partition — and the machine either mounts the wrong thing or refuses to finish booting. The fix costs nothing: reference filesystems by UUID= instead.

The cure is to name filesystems by something that travels with the filesystem rather than with the discovery order. The best choice is the UUID — a 128-bit identifier written into the filesystem's superblock when it's created, globally unique, and unchanged for the life of the filesystem (only a reformat assigns a new one). It doesn't matter what slot the disk is in or what letter the kernel hands it; the UUID is the same. Find it with blkid or lsblk -f:

blkid /dev/sdb1
/dev/sdb1: UUID="98765432-dcba-10fe-5432-1098fedcba76" TYPE="ext4"

Then the fstab line becomes:

UUID=98765432-dcba-10fe-5432-1098fedcba76  /data  ext4  defaults  0  2

This is also why your bootloader uses UUIDs (or their cousin, the filesystem LABEL, and on the partition table side the GPT PARTUUID): GRUB has to find the root filesystem before Linux is even running, when device names are at their least trustworthy. The kernel command line you'll see in a healthy modern install reads root=UUID=..., not root=/dev/sda2, for exactly this reason. Stable names for an unstable world.

A Mount Hides Whatever Was Underneath

Here is the other great confusion, and it has sent more than one person hunting for "deleted" files that were never deleted. Mounting over a directory hides — shadows — whatever that directory already contained. It does not erase it. The old contents are still on the underlying filesystem, exactly where they were; they're just covered up, like a rug thrown over a trapdoor. While the mount is active you can't see them, can't ls them, can't open them. Unmount, and they reappear instantly, untouched.

The classic way to walk into this: you create /mnt/data, copy a few gigabytes of files into it before mounting the new disk, then mount the disk on top. Your files are gone — ls /mnt/data now shows the (empty) new disk. Panic. But nothing was lost: those gigabytes are sitting on the root filesystem, shadowed under the mount. They're also the reason for a maddening variant of "disk full": the root disk reads as nearly full, yet the directory you suspect — say /var/log with a log volume mounted over it — looks tiny when you ls it. The space is consumed by files written into /var/log while no volume was mounted there, now hidden behind the mount. Unmount it and the "missing" gigabytes are right there.

Pro Tip

When a filesystem is full but the obvious directory looks empty, suspect shadowed files. Mount a fresh empty directory somewhere harmless and bind-mount the parent there, or temporarily unmount the overlaying volume, and inspect what's hiding underneath. The space is almost always real files written before the mount existed.

The mental model that fixes this forever: a mount point is a window, not a container. When the window is open (mounted) you see through it to the other filesystem; when it's closed (unmounted) you see the wall behind it. The wall was always there.

Reading and Writing /etc/fstab

/etc/fstab — the "filesystem table" — is the list of mounts Linux sets up automatically, chiefly at boot. Each non-comment line describes one filesystem in six whitespace-separated fields. Most fstab confusion comes from not knowing what those six columns mean, so here's every one.

# <device>                                    <mount point>  <type>  <options>          <dump> <pass>
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890      /              ext4    defaults            0      1
UUID=98765432-dcba-10fe-5432-1098fedcba76      /data          xfs     defaults,noatime    0      2
UUID=ABCD-1234                                 /boot/efi       vfat    umask=0077          0      2
192.0.2.10:/exports/backup                     /mnt/backup     nfs     defaults,_netdev    0      0
  1. Device (the source). What to mount. Use UUID=... (see the section above — this is the right answer almost every time). You may also see a filesystem LABEL=..., a PARTUUID=... for the partition, a raw /dev/... path (fragile), or for a network mount a host:/export (NFS) or //host/share (CIFS) address.

  2. Mount point. Where on the tree it attaches — the directory. For swap, this field is the word none (or swap), because swap isn't part of the directory tree at all.

  3. Type. The filesystem type: ext4, xfs, btrfs, vfat, nfs, swap, and so on. You can write auto to let the kernel probe and guess, but naming it explicitly is safer and avoids a wrong guess on an overwritten device.

  4. Options. A comma-separated list of mount options (covered next). defaults is shorthand for a sensible common set (rw,suid,dev,exec,auto,nouser,async).

  5. Dump. A relic. A single digit consulted by the ancient dump backup utility to decide whether to back this filesystem up. Almost nobody runs dump today, so this is essentially always 0. It survives purely because the file format has six columns and removing one would break a million scripts.

  6. Pass (fsck order). When the boot-time fsck check runs, this controls order. 1 means "check first" and is reserved for the root filesystem. 2 means "check after root," used for other permanent local filesystems. 0 means "never check at boot" — correct for network mounts, swap, and anything that handles its own integrity. Filesystems with the same non-zero pass number on different physical disks are checked in parallel.

Pro Tip

Never reboot to test an /etc/fstab edit. Run mount -a first — it processes every line in the file exactly as boot would, but while you still have a working shell to fix mistakes. If mount -a is silent, your fstab is good. If it errors, you just saved yourself an emergency-shell rescue. Test before you trust your only way back in to a file you just edited.

Mount Options Worth Knowing

Options are the comma-separated knobs in field four (or after -o on the command line). A handful earn their keep on a server:

  • ro / rw — mount read-only or read-write. ro is invaluable for forensics or for protecting a reference volume; it's also the state a filesystem flips itself into when it hits errors (see read-only filesystem).
  • noatime — stop updating each file's access time on every read. By default Linux records "when was this file last read," which means a read turns into a tiny write. On a busy server — a web root, a mail spool, a database — that overhead is pure waste. noatime switches it off and is one of the safest, most common performance tweaks there is. (The default these days is relatime, a compromise that updates atime only occasionally; noatime goes all the way.)
  • nosuid — ignore the setuid/setgid bits on files in this filesystem, so a binary there can't quietly run with elevated privileges. Sensible on any volume holding user-supplied data or removable media.
  • nodev / noexec — refuse to honour device nodes / refuse to execute binaries. The hardening trio nodev,nosuid,noexec is the standard armour for /tmp, /home, and untrusted mounts.
  • _netdev — marks a mount as depending on the network. This one prevents a specific, nasty boot hang: without it, the boot sequence may try to mount your NFS or CIFS share before networking is up, then sit there waiting forever. _netdev tells the init system "hold this until the network is ready." Put it on every network mount, always.

A network mount line that won't strand you at boot therefore looks like this:

192.0.2.10:/exports/backup  /mnt/backup  nfs  defaults,_netdev,soft,timeo=30  0  0

_netdev so boot waits for the network, soft and timeo so a dead server eventually returns an error instead of hanging your processes forever. A hard, _netdev-less NFS line is the textbook recipe for a load average climbing into three digits while the CPU sits idle — every process that touched the dead mount stuck in uninterruptible sleep, going nowhere.

Listing What's Mounted

Two tools, and you reach for the second one more.

mount with no arguments dumps the kernel's full mount table — every real filesystem plus dozens of virtual ones (proc, sysfs, tmpfs, cgroup, …). It's complete but noisy.

mount

findmnt is the modern, structured view: a tidy tree, columns, and filters. It reads the same kernel data and presents it like something designed this century.

findmnt
TARGET                SOURCE     FSTYPE  OPTIONS
/                     /dev/sda2  ext4    rw,relatime,errors=remount-ro
├─/boot/efi           /dev/sda1  vfat    rw,relatime,fmask=0077,dmask=0077
├─/data               /dev/sdb1  xfs     rw,noatime,attr2,inode64
└─/mnt/backup         192.0.2.10:/exports/backup  nfs  rw,_netdev,soft

Filter to real on-disk filesystems and skip the virtual clutter:

findmnt -t ext4,xfs,btrfs,vfat,nfs

Or ask one targeted question — "what's mounted at /data, and is it read-write?":

findmnt /data

The OPTIONS column is where you confirm a volume actually mounted read-write, or catch a filesystem that has quietly gone ro after an I/O error — the early warning sign of a failing disk.

When umount Says "Target Is Busy"

You try to unmount and Linux refuses:

umount: /data: target is busy.

This is not a malfunction — it's a safeguard. Something is still using the filesystem, and pulling it out from under that something would corrupt data or crash a process. "Busy" means one of a few things: a process has a file open on the mount, a process has its working directory inside the mount (you yourself, sitting in /data in another terminal, is the most common culprit — just cd / and try again), or another mount is stacked on top.

To find the offender, ask which processes are using the path. lsof lists open files under it; fuser does the same and can signal them:

lsof +D /data          # every open file under /data, with the PID holding it
fuser -vm /data        # processes using the mount, verbose

Once you know who's holding it, you stop that process (or cd out of the directory) and the unmount succeeds cleanly. That is the right answer the overwhelming majority of the time.

When you genuinely can't stop the holder — a wedged process, a dead network mount whose server vanished — there's the lazy unmount:

umount -l /data

-l detaches the filesystem from the tree immediately (so /data is free and new accesses go to the underlying directory) but defers the actual teardown until the last open reference is released. It's the escape hatch for a hung NFS mount whose server is never coming back. Use it knowingly, not reflexively: a lazy unmount on a local disk with active writers can lose buffered data, because you've told the kernel "let go whenever," not "flush and let go now." For a healthy filesystem, find the holder with lsof and unmount it properly; save -l for the genuinely stuck.

Bind Mounts: The Same Files in Two Places

A bind mount makes an existing directory appear at a second location, without copying anything. It's not a symlink and not a hard link — it's a true second mount point onto the same underlying files, so it works across the boundary where symlinks get awkward (inside a chroot, for instance) and applies to a whole subtree at once.

mount --bind /srv/www/shared  /var/www/site-a/shared

Now the two paths show the identical files; write through one and you see it through the other, because they are the same directory presented twice. To make it survive a reboot, add the bind option in fstab:

/srv/www/shared  /var/www/site-a/shared  none  bind  0  0

Bind mounts show up everywhere once you notice them: exposing one slice of a filesystem into a chroot or container, giving an application a path it insists on without moving the data, or read-only-exposing a config directory (mount --bind -o ro). They're a small feature with an outsized number of uses.

A Word on Mount Namespaces and Containers

Everything above assumes one mount table for the whole machine. That assumption is what containers quietly break — and understanding it demystifies a lot of Docker.

The kernel can give a group of processes their own mount table, isolated from the host's. This is a mount namespace, one of the half-dozen namespace types (alongside network, PID, user, and others) that together make a container. Inside the namespace, a process sees its own root filesystem, its own mounts, its own /proc — and crucially it cannot see or affect the host's mounts. Mount points created inside don't leak out; the host's mounts don't clutter the inside. That's how a container gets to believe it owns a clean little machine while it's really sharing one kernel with everything else on the box.

So a container image's filesystem is, underneath the branding, an assembly of mounts — typically a stacked (overlay) read-only image layer with a writable layer on top, plus a fistful of bind mounts for the volumes you passed in — all set up inside a fresh mount namespace before your process starts. Docker, Podman, and systemd's own sandboxing all stand on this one kernel feature. The humble mount syscall you met at the top of this page is, it turns out, also the load-bearing wall under the entire container revolution. Not bad for a list the kernel keeps.

Cheat Sheet

# --- Mount and unmount ---
mount /dev/sdb1 /data                 # mount a device on a directory
mount -o ro,noatime /dev/sdb1 /data   # mount with explicit options
mount -t nfs 192.0.2.10:/exp /mnt/nfs # mount an NFS share
umount /data                          # unmount (by mount point)
umount /dev/sdb1                       # unmount (by device — same effect)
umount -l /data                       # LAZY unmount: detach now, clean up later

# --- fstab ---
mount -a                              # mount everything in fstab (TEST after editing!)
mount /data                           # mount one fstab entry by its mount point
findmnt --verify                      # sanity-check /etc/fstab for errors

# --- List what's mounted ---
mount                                 # raw kernel mount table (noisy)
findmnt                               # structured tree of all mounts
findmnt -t ext4,xfs,nfs               # only these filesystem types
findmnt /data                         # just this mount, with its options
cat /proc/mounts                      # the kernel's own view, as a file

# --- Identify devices (for fstab) ---
blkid                                 # UUID + TYPE for every block device
blkid /dev/sdb1                       # ...for one device
lsblk -f                              # device → FS type → UUID → mountpoint tree

# --- "Target is busy" ---
lsof +D /data                         # open files under the mount
fuser -vm /data                       # processes using the mount
cd / ; umount /data                   # the usual fix: you were standing in it

# --- Bind mounts ---
mount --bind /src /dst                # same files, second location
mount --bind -o ro /src /dst          # ...read-only at the new location

# --- Remount (change options without unmounting) ---
mount -o remount,ro /data             # flip a live mount to read-only
mount -o remount,rw /                 # recover root after it went read-only

Gotchas

Roughly in order of how often they bite:

  • Device names drift; use UUIDs in fstab. An fstab line pointing at /dev/sdb1 will eventually point at the wrong disk after a cable swap, an added drive, or a probe-order change — and the box won't boot. Use UUID= (from blkid) and the problem disappears.
  • Mounting hides what was underneath. Files already in a mount point don't vanish when you mount over them — they're shadowed, still on the underlying filesystem, and they reappear the instant you unmount. This is also the answer to "disk full but the directory looks empty."
  • Always mount -a before rebooting after an fstab edit. It applies the whole file the way boot would, while you still have a shell to fix typos. Skipping this is the leading cause of self-inflicted boot failures.
  • Forgetting _netdev on network mounts hangs the boot. Without it the init system tries to mount the share before the network exists and may wait forever. Add _netdev to every NFS/CIFS line.
  • "Target is busy" is almost always you. A shell sitting inside the mount counts as a user. cd / and try the umount again before reaching for anything heavier.
  • umount -l on a healthy local disk can lose data. Lazy unmount defers the flush; on a busy local volume that means buffered writes may never land. Reserve it for genuinely stuck (usually network) mounts.
  • Omitting the type lets the kernel guess. On a freshly overwritten device the guess can be wrong, and you mount garbage. Name the type explicitly, and verify an unfamiliar device with blkid first.

History and Philosophy

The mount model goes all the way back to the original Unix at Bell Labs in the early 1970s. Ken Thompson and Dennis Ritchie made a decision that still feels modern: rather than expose storage as a set of separate, lettered volumes the way the systems of the era (and later DOS, and later Windows) did, they let every filesystem be spliced into one shared tree. There was one root, /, and every other disk hung off a directory somewhere within it. The user — and most programs — never had to know or care which physical device a given file lived on. A path was a path.

It's hard to overstate how much that single choice shaped everything after. Because there's one namespace, a program that walks / walks the whole machine. Because mounting is just "attach this filesystem at that directory," you can slide a faster disk under /var, move /home onto a network share, or graft a read-only image and a writable layer together — all without any application noticing, because to the application it's still just files under a path. The same primitive that organised a 1970s minicomputer's two disk packs is, unchanged in spirit, what lets a container present a curated little world to the process inside it. Good abstractions age well.

The philosophy is the familiar Unix one: build a small, sharp mechanism — attach a filesystem at a point in the tree — and let everything else (boot configuration, removable media, network storage, containers) be expressed in terms of it rather than as special cases. The kernel keeps a list; userspace decides what goes on it. Decades of storage technology have come and gone, and the mount syscall has barely changed, because the idea underneath it was right the first time.

See Also

  • filesystem — what a mount actually attaches to the tree
  • uuid — the stable identifier that belongs in /etc/fstab instead of /dev/sdX
  • block device — the raw device a local filesystem lives on
  • partition — the slice of a disk that usually becomes a mount source
  • nfs — network filesystems, why they want _netdev, and how they hang
  • lvm — logical volumes that get mounted just like a partition
  • /etc/fstab — the boot-time table of what mounts where, column by column
  • mount — attach a filesystem, or list what's attached
  • umount — detach a filesystem, including the lazy -l escape hatch
  • lsblk — the block-device-to-mountpoint tree, with UUIDs
  • read-only filesystem — when a mount flips itself to ro after errors
  • disk full — including the "full but empty-looking directory" shadowed-files trap

Did a mount quietly vanish, fill up, or flip to read-only without anyone noticing?

CleverUptime watches every mounted filesystem on your servers for usage creeping toward full or a volume that's stopped accepting writes, and tells you in plain language which mount is in trouble before it takes an app down with it.

Want to see your own server's health right now? One command, no signup, no install.

Check your server →