The first time I hopped from Windows to Linux full-time, the thing that threw me off most wasn’t the terminal — it was the directory structure. No C:\, no drive letters, just one single tree starting at / with everything, including other disks, grafted onto it somewhere. It took me a while to really internalize that this isn’t a limitation, it’s actually a cleaner design once you understand it. This guide covers that structure end to end: the standard layout, how mounting actually works, filesystem types, permissions, and the practical commands you’ll use to manage all of it.
The Unified Tree: Why Linux Has No Drive Letters
Every Linux system has exactly one root directory, written as /. Every single file, directory, and device on the system — regardless of which physical disk, partition, network share, or virtual filesystem it actually lives on — appears somewhere under that one tree. Where Windows would show C:\, D:\, E:\ as separate namespaces, Linux instead mounts additional filesystems onto directories (called mount points) within the existing tree, so a second hard disk might simply appear as /data, and a USB drive might show up at /media/usbdrive.
You can see this in action with lsblk, which shows block devices and where they’re mounted:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 254:0 0 256G 0 disk /
vdb 254:16 0 9.7M 1 disk /opt/rclone
vdc 254:32 0 668K 1 disk /mnt/skills/public
vdd 254:48 0 5.5M 1 disk /mnt/skills/examples
Here, vda (a 256GB disk) is mounted as the root filesystem /, while three other separate disks are mounted at completely ordinary-looking directory paths. From a user’s perspective, walking into /mnt/skills/public looks exactly like walking into any other directory, even though it’s physically a different device entirely. That’s the whole trick — mounting stitches separate storage into one seamless namespace.
The Filesystem Hierarchy Standard (FHS)
Almost every major Linux distribution follows the Filesystem Hierarchy Standard (FHS), a specification maintained by the Linux Foundation that defines what each top-level directory is supposed to contain. Knowing this layout means you can walk onto almost any Linux system, from any distro, and immediately know roughly where to find things.
ls -la /
lrwxrwxrwx bin -> usr/bin
drwxr-xr-x boot
drwxr-xr-x dev
drwxr-xr-x etc
drwxr-xr-x home
lrwxrwxrwx lib -> usr/lib
lrwxrwxrwx lib64 -> usr/lib64
drwx------ lost+found
drwxr-xr-x media
drwxr-xr-x mnt
drwxr-xr-x opt
dr-xr-xr-x proc
drwx------ root
...
Here’s what each of these is for:
| Directory | Purpose |
|---|---|
/bin | Essential user command binaries (often symlinked to /usr/bin on modern distros) |
/boot | Boot loader files: kernel image, initramfs, GRUB configuration |
/dev | Device files representing hardware (disks, terminals, USB devices) |
/etc | System-wide configuration files |
/home | Per-user home directories (/home/alice, /home/bob) |
/lib, /lib64 | Shared libraries needed by binaries in /bin and /sbin |
/media | Mount points for removable media (USB drives, CDs) |
/mnt | Conventional location for temporarily mounted filesystems |
/opt | Optional, third-party, or self-contained application packages |
/proc | Virtual filesystem exposing live kernel and process information |
/root | Home directory for the root user (distinct from /) |
/run | Runtime data since last boot: PID files, sockets |
/sbin | System binaries, typically for administrative use |
/srv | Data served by the system, e.g. web server content |
/sys | Virtual filesystem exposing kernel/device/driver information (sysfs) |
/tmp | Temporary files, often cleared on reboot |
/usr | The bulk of installed software: binaries, libraries, docs |
/var | Variable data: logs, mail spools, caches, databases |
A quirk worth knowing: on many modern distributions (Debian, Ubuntu, Fedora, Arch), /bin, /sbin, /lib, and /lib64 are now symlinks pointing into /usr/bin, /usr/sbin, /usr/lib, etc. — this is called the “usr merge,” and it consolidates what used to be a split between “essential for early boot” and “everything else” into a single location, simplifying packaging and read-only root setups.
Mount Points Explained
A mount point is just an ordinary directory that a filesystem has been attached to. Before mounting, it’s an empty directory (or one containing whatever was there before); after mounting, its contents are replaced (from the user’s view) by the contents of the mounted filesystem.
Viewing current mounts:
mount | head -5
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=2042076k,nr_inodes=510519,mode=755)
tmpfs on /dev/shm type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
Or with findmnt, which shows the tree structure of mounts more clearly:
findmnt
TARGET SOURCE FSTYPE OPTIONS
/ /dev/vda ext4 rw,relatime,resuid=65534,resgid=65534
|-/proc proc proc rw,relatime
|-/sys sysfs sysfs rw,relatime
| `-/sys/fs/cgroup tmpfs tmpfs rw,relatime
...
Every entry has a source (the device or virtual filesystem), a target (the mount point directory), a filesystem type, and a set of options controlling behavior (read-only vs read-write, access timestamps, and more).
Persistent mounts — ones that should be attached automatically every boot — are defined in /etc/fstab, a plain text file with one line per mount, in the format:
<device> <mount point> <filesystem type> <options> <dump> <pass>
For example:
UUID=1234-5678 /data ext4 defaults 0 2
Filesystem Types
Linux supports a wide range of filesystem types, each with different tradeoffs:
| Filesystem | Notes |
|---|---|
ext4 | The long-standing default on most distributions; mature, reliable, journaling |
xfs | High-performance, especially for large files; default on RHEL/CentOS/Fedora |
btrfs | Copy-on-write, built-in snapshots and volume management; default on openSUSE |
zfs | Advanced snapshotting, checksumming, pooling; common in storage-heavy setups |
tmpfs | RAM-backed, volatile, gone on reboot — used for /tmp, /dev/shm |
vfat/exfat | Cross-compatible with Windows, common for USB drives |
overlay/overlayfs | Layered filesystem, foundational to how Docker/container images work |
nfs/cifs | Network filesystems for shared remote storage |
Checking the type of an existing mount:
df -hT
Filesystem Type Size Used Avail Use% Mounted on
tmpfs tmpfs 2.0G 72K 2.0G 1% /dev/shm
/dev/vda ext4 252G 8.6G 10G 47% /
The -T flag adds the filesystem type column, which plain df -h omits.
Inodes and How Files Actually Work
Understanding Linux file storage means understanding inodes. Every file on a traditional Linux filesystem (ext4, xfs, etc.) is represented by an inode — a data structure holding metadata about the file (permissions, owner, size, timestamps, and pointers to the actual data blocks on disk) but not the filename itself. The filename lives in the containing directory, which is really just a mapping of names to inode numbers.
This is why:
- Multiple filenames (hard links) can point to the exact same inode/data.
- Deleting a file just removes one name-to-inode mapping; the data isn’t actually freed until the last link and last open file handle referencing that inode are gone.
- Renaming a file within the same filesystem is instant, because it’s just a metadata change, not a data copy.
Checking inode usage:
df -i
Checking filesystem details, including inode counts, with stat:
stat -f /
File: "/"
ID: 0 Namelen: 255 Type: ext2/ext3
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 66053021 Free: 63812211 Available: 2617324
Inodes: Total: 16777216 Free: 16583239
Running out of inodes (even with plenty of disk space free) is a real, if less common, failure mode — usually caused by an application creating huge numbers of tiny files. df -i catches this; df -h alone won’t show it.
File Permissions and Ownership
Every file and directory carries an owner, a group, and a permission set for owner/group/others, viewable with:
ls -l
-rw-r--r-- 1 root root 76 Jul 31 01:37 container_info.json
Reading left to right: file type (- for regular file, d for directory, l for symlink), then three permission triads (owner, group, other), each representing read (r), write (w), and execute (x).
Common commands for managing this:
chmod 755 script.sh # rwxr-xr-x
chmod u+x script.sh # add execute for owner only
chown alice:developers file.txt # change owner and group
chgrp developers file.txt # change group only
Practical System Administration Examples
Finding what’s eating disk space:
du -sh /var/* 2>/dev/null | sort -rh | head -10
Checking free space across all mounted filesystems:
df -h
Locating which filesystem a given directory lives on:
df -h /home/alice
Finding large files system-wide:
find / -xdev -type f -size +500M 2>/dev/null
The -xdev flag here matters — it prevents find from crossing into other mounted filesystems (like network mounts or /proc), keeping the search scoped to the current filesystem only.
Safely creating and testing a new mount point:
sudo mkdir /data
sudo mount /dev/sdb1 /data
df -h /data
Troubleshooting
- “No space left on device” despite
df -hshowing free space → check inodes withdf -i; you may have exhausted inode count, not byte capacity. - A deleted file’s space isn’t reclaimed → a process likely still has the file open; check with
lsof | grep deletedor via/proc/<PID>/fd. - A mount point directory appears “wrong” or shows old files → the filesystem may have failed to mount, and you’re actually looking at the underlying (empty or stale) directory on the root filesystem instead.
- Filesystem marked read-only unexpectedly → often a sign of detected corruption; the kernel remounts read-only to prevent further damage. Check
dmesgfor the underlying I/O or filesystem error, and plan anfsckduring a maintenance window.
Performance Considerations
ext4andxfsare both solid general-purpose choices;xfstends to perform better with very large files and high-concurrency workloads, whileext4has a slight edge in general-purpose, mixed small-file workloads on some benchmarks.- Mount options matter:
noatime(skip updating access-time metadata on every read) can meaningfully reduce write overhead on read-heavy workloads, since without it, every single file read still triggers a metadata write. - For temporary, performance-critical data that doesn’t need to survive a reboot,
tmpfs(RAM-backed) is dramatically faster than disk-backed storage — this is why/tmpis tmpfs on many modern distributions.
Security Implications
- Directory and file permissions are your first line of defense; a misconfigured world-writable directory (
chmod 777) is a common and serious mistake, especially for anything reachable by application code. - Mount options like
noexec,nosuid, andnodevcan be applied to filesystems like/tmpto prevent execution of binaries, SUID privilege escalation, and device file creation from that mount — a standard hardening step on multi-user or web-facing systems. - Be cautious with world-readable home directories or config files containing credentials —
chmod 600for sensitive files is the safe default.
Compatibility Across Distributions
The FHS layout is broadly consistent across Debian, Ubuntu, RHEL, CentOS, Fedora, and openSUSE, though defaults diverge in a few places: RHEL-family distros default to xfs, Debian/Ubuntu traditionally default to ext4, and openSUSE has long favored btrfs with snapshot integration via Snapper. Arch Linux and other rolling-release distros generally follow FHS closely as well, though with slightly more flexibility left to the user during installation.
Symbolic Links vs Hard Links in the Directory Tree
Since the directory structure relies so heavily on the inode model described earlier, it’s worth being precise about the two kinds of links you’ll encounter while navigating it, since they behave quite differently.
A hard link (ln source target) creates a second directory entry pointing at the exact same inode as the original — there’s no “original” and “copy” distinction at the filesystem level; both names are equally valid references to the same data, and the data isn’t freed until every hard link to it is removed. Hard links can’t cross filesystem boundaries (since inode numbers are only unique within a single filesystem) and generally can’t reference directories, only regular files.
A symbolic link (ln -s target linkname), by contrast, is a small special file that simply contains a path string pointing somewhere else — you can see this distinction directly in a long listing, where symlinks show an l file-type character and an arrow (->) pointing at their target, as seen earlier with /bin -> usr/bin. Symlinks can cross filesystem boundaries freely, can point at directories, and can even point at a target that doesn’t exist (a “dangling” symlink), which hard links structurally cannot do.
ln /var/log/syslog /tmp/syslog_hardlink
ln -s /var/log/syslog /tmp/syslog_symlink
Knowing which kind of link you’re looking at matters for troubleshooting: deleting the original file behind a hard link leaves the hard-linked copy completely intact and readable, while deleting the original behind a symlink leaves the symlink pointing at nothing, breaking it.
Summary
Linux’s single unified directory tree, with separate storage devices grafted on via mount points, takes a bit of getting used to coming from a drive-letter world — but it’s a genuinely elegant design once it clicks. Knowing the standard FHS layout, how mounting and /etc/fstab work, the tradeoffs between filesystem types, and how inodes and permissions underpin everything gives you the foundation for basically all serious Linux system administration work.
References
- Filesystem Hierarchy Standard: https://refspecs.linuxfoundation.org/fhs.shtml
man 5 fstabman 8 mountman 5 ext4,man 5 xfs- Red Hat Storage Administration Guide (RHEL documentation)