Linux Filesystems — Deep Dive
Before learning commands like:
df -h
du -sh
ls -i
mount
findwe need to understand what a filesystem actually is.
1. First: What is a filesystem?
Let’s start with something very simple.
Your SSD is hardware.
For example:
SSD
└── 500 GBBut an SSD by itself doesn’t understand concepts like:
/home/user/file.txt
/var/log/app.log
/etc/nginx/nginx.confSomething needs to organize the storage.
That’s the job of a filesystem.
A filesystem defines how data is organized and accessed on a storage device.
Common Linux filesystems include:
ext4
XFS
BtrfsSo think of the layers like this:
Application
↓
Linux system calls
↓
Filesystem
↓
Block device
↓
Storage driver
↓
SSDFor example:
cat /home/user/file.txteventually involves Linux asking the filesystem:
“Where is the data belonging to
file.txt?"
The filesystem finds the relevant metadata and storage blocks, and Linux reads the data.
2. SSD vs Filesystem
This distinction is extremely important.
Suppose you have:
1 TB SSDThat’s the physical storage device.
You could partition it:
SSD
│
├── Partition 1
│
├── Partition 2
│
└── Partition 3Then put filesystems on those partitions:
SSD
│
├── Partition 1
│ └── ext4 filesystem
│
├── Partition 2
│ └── XFS filesystem
│
└── Partition 3
└── ext4 filesystemSo:
Storage device ≠ partition ≠ filesystem.
These are different concepts.
3. What does / mean?
Now we get to Linux’s most important filesystem concept.
Linux has a single directory tree.
At the top is:
/This is called the root directory.
Everything accessible through the normal filesystem hierarchy appears somewhere underneath /.
For example:
/
├── etc
├── home
├── var
├── usr
├── tmp
├── dev
├── proc
└── sysCompare that with Windows:
C:\
D:\
E:\Linux doesn’t normally work that way.
Instead:
/
│
├── home
├── var
├── etc
└── ...Everything starts from /.
/
│
├── etc → configuration
├── var → changing data/logs
├── home → user files
├── usr → programs/libraries
├── tmp → temporary data
├── dev → devices/special interfaces
├── proc → process/kernel information
└── sys → devices/drivers/kernel model4. /etc — Configuration
Think:
/etc→ system configuration
You’ll find configuration files for many services and system components.
For example:
/etc/hosts
/etc/passwd
/etc/ssh/
/etc/nginx/You might have:
cat /etc/hostsor:
ls /etc/ssh/For Nginx:
/etc/nginx/
├── nginx.conf
├── conf.d/
└── sites-enabled/So when you’re troubleshooting a Linux service:
Service problem
↓
Check configuration
↓
/etc/...5. /var — Data that changes
var comes from variable.
Think:
/var→ data that changes while the system runs
For example:
/var/log
/var/lib
/var/cache/var/log
Very important for troubleshooting.
You may find:
/var/log/syslog
/var/log/auth.log
/var/log/nginx/For example:
ls -lh /var/logIf your server’s disk suddenly fills up, /var/log is one place you might investigate.
6. /var/lib
This is another important directory. Applications can store persistent state here.
For example, depending on your distribution and software:
/var/lib/docker/
/var/lib/mysql/
/var/lib/postgresql/
/var/lib/...Think:
/var/lib→ application/system state that needs to persist.
This is particularly important with servers.
For example, Docker images and container-related data can consume significant disk space.
7. /home
This is where normal users generally have their home directories.
For example:
/home/
├── alice/
├── bob/
└── oshadhi/If the username is oshadhi:
/home/oshadhi/You might have:
/home/oshadhi/
├── Documents/
├── Downloads/
├── projects/
└── .ssh/The . is important.
Files beginning with . are normally hidden from a regular ls.
Try:
lsversus:
ls -la8. /usr
This one confuses many beginners.
People sometimes think:
“usrmeans user files."
That’s not really the right way to think about it.
Modern Linux systems use /usr for much of the user-space software and supporting data.
A place where much of the Linux operating system’s user-space programs, libraries, and shared data are installed.
So:
/home → my personal data
/usr → operating-system/user-space softwareFor example:
/usr/bin
/usr/sbin
/usr/lib
/usr/shareWhat is /usr/bin?
This is probably the easiest part.
Try:
ls /usr/binYou’ll see a huge number of programs.
For example:
/usr/bin/
├── ls
├── cat
├── grep
├── ssh
├── python3
├── curl
├── find
└── ...These are executable programs.
For example, when you type:
lsyou are actually running a program.
You can find where it is:
which lsYou may get:
/usr/bin/lsSo:
You type:
ls
↓
Shell finds:
↓
/usr/bin/ls
↓
Operating system executes itThis connects directly to what we learned about processes.
Conceptually:
/usr/bin/ls
│
│ execute
▼
Process
│
▼
CPUSo /usr/bin/ls is not a process.
It’s a program stored on disk.
When you run it, Linux creates a process to execute it.
What does /usr/sbin mean?
sbin = system binaries
These traditionally contain programs mainly intended for system administration.
For example:
/usr/sbin/
├── nginx
├── sshd
└── other system daemons/tools
bintraditionally contains general-purpose executables, whilesbintraditionally contains system-administration executables.
9. /tmp
Think:
temporary files
Applications can use:
/tmpfor temporary data.
For example:
echo "hello" > /tmp/test.txtThen:
cat /tmp/test.txtYou might see:
helloDon’t treat /tmp as permanent storage.
Depending on the distribution/configuration, temporary files may be removed during reboot or by cleanup mechanisms.
10. Now things become REALLY interesting: /dev
This is where the phrase:
“Everything is a file.”
starts becoming interesting.
Look at:
ls /devYou may see things like:
/dev/null
/dev/random
/dev/zero
/dev/sda
/dev/nvme0n1But these aren’t ordinary text files.
They are special filesystem objects, often representing devices or kernel interfaces.
11. /dev/null
This is one of the most famous Linux examples.
Try:
echo hello > /dev/nullYou won’t see:
helloWhere did it go?
Nowhere useful.
/dev/null is a special device that discards data written to it.
Conceptually:
Program
↓
/dev/null
↓
Data disappearsThat’s why you’ll often see:
command > /dev/null12. /dev/zero
Another interesting one:
/dev/zeroReading from it produces zero bytes.
For example:
head -c 10 /dev/zeroIt provides zero-valued bytes.
Again:
/dev/zeroisn't a normal file sitting on your SSD containing billions of zeros.
It's a special device interface provided by the kernel.
This is why:
"Everything is a file"
is a useful Linux mental model, but not literally everything is an ordinary file.
13. /dev/sda and /dev/nvme0n1
Now let’s connect this to your SSD.
On some systems you might see:
/dev/sdaHistorically, Linux uses names such as:
/dev/sda
/dev/sdb
/dev/sdcfor disks.
Think:
/dev/sda → first disk
/dev/sdb → second disk
/dev/sdc → third diskFor example:
Computer
│
├── Disk 1 → /dev/sda
├── Disk 2 → /dev/sdb
└── Disk 3 → /dev/sdcWhat about /dev/sda1?
Now we add a number:
/dev/sda1
↑
partition 1So:
/dev/sda - Disk 1
│
├── /dev/sda1 - Disk1, Partition 1
├── /dev/sda2 - Disk1, Partition 2
└── /dev/sda3 - Disk1, Partition 3On NVMe systems:
/dev/nvme0n1These can represent storage devices.
For example:
/dev/nvme0n1might be your physical NVMe SSD.
Get Oshadhi Wickramasinghe’s stories in your inbox
Join Medium for free to get updates from this writer.
Let’s split it:
/dev/nvme0n1
│ │ │
│ │ └── n1 = namespace 1
│ └──── 0 = controller 0
└────── nvme = NVMe deviceSo:
/dev/nvme0n1means approximately:
NVMe controller 0, namespace 1
Then partitions could appear as:
/dev/nvme0n1p1
/dev/nvme0n1p2
/dev/nvme0n1p3Conceptually:
SSD
│
└── /dev/nvme0n1 - Your NVMe storage device
│
├── /dev/nvme0n1p1 - Partition 1
├── /dev/nvme0n1p2 - Partition 2
└── /dev/nvme0n1p3 - Partition 3You can inspect this with:
lsblkNVMe is a technology/protocol used for accessing SSD storage, especially SSDs connected through PCIe.
PCIe provides much higher bandwidth and supports many parallel queues, which makes NVMe very efficient for modern systems.
The easiest way to understand it is to separate SSD and NVMe.
SSD vs NVMe
SSD describes the type of storage technology:
SSD = Solid State Drive
It uses flash memory instead of spinning disks like an old HDD.
NVMe describes how the computer communicates with the SSD:
NVMe = Non-Volatile Memory Express
So an NVMe SSD is essentially:
CPU
│
│ PCIe
▼
NVMe SSD
│
▼
Flash MemorySSD = what the storage is. NVMe = how a modern SSD communicates with the computer.
14. /proc — The filesystem that isn't really on disk
Now we reach one of my favorite Linux concepts.
Try:
ls /procYou’ll see things like:
1
2
3
...
cpuinfo
meminfo
uptime
versionYou might ask:
“Where are these files stored?”
They’re generally not stored on your SSD.
/proc is a virtual filesystem exposed by the Linux kernel.
It provides information about:
processes
CPU
memory
kernel
system state15. /proc/1
Let’s say:
PID 1 = systemdYou can run:
cat /proc/1/statusYou’re essentially asking the kernel:
“Give me information about process 1.”
You may see information about:
Name
State
Pid
PPid
Uid
Gid
memory
threadsThis is a beautiful connection:
Process
↓
PID 1
↓
/proc/1/
↓
Kernel exposes process information16. /proc/meminfo
Remember our memory lesson?
We used:
free -hWhere does a lot of that information ultimately come from?
Try:
cat /proc/meminfoYou’ll see:
MemTotal
MemFree
MemAvailable
Buffers
Cached
SwapTotal
SwapFree
...So:
free -h
↓
kernel memory information
↓
/proc/meminfoNow our filesystem lesson connects to our memory lesson.
17. /proc/cpuinfo
Similarly:
cat /proc/cpuinfocan expose CPU information.
Again:
/procis giving you a window into the kernel’s view of the system.
18. /sys — Another virtual filesystem
Now:
/sysis also very interesting.
/sys is commonly called sysfs.
It exposes information about:
- devices
- drivers
- hardware
- kernel device model
For example:
ls /sys/class/net/You might see:
eth0
loor:
ens33
loThese represent network interfaces.
So we can remember:
/proc → processes + kernel/system information
/sys → devices + drivers + hardware model19. Now let’s understand INODES
This is one of the most important filesystem concepts.
Suppose you create:
touch hello.txtYou might think Linux stores:
hello.txt
↓
dataBut internally, it’s more interesting.
A filesystem maintains metadata about files.
One important structure is the:
inode
An inode can contain information such as:
File type
Permissions
Owner
Group
Size
Timestamps
Links
Pointers/references to data blocksYou can see inode numbers with:
ls -iFor example:
123456 hello.txtHere:
123456is the inode number.
20. Filename vs inode
This distinction is VERY important.
Think:
Filename
↓
inode
↓
file metadata
↓
data blocksThe filename is essentially an entry in a directory that points to an inode.
So:
hello.txt
│
▼
inode 123456
│
├── permissions
├── owner
├── size
└── data block referencesThis understanding makes hard links much easier later.
21. File data is stored in blocks
Suppose:
hello.txtcontains:
Hello Linux!The filesystem stores the actual data in storage blocks.
Conceptually:
hello.txt
↓
inode
↓
data blocks
↓
SSDThe inode helps the filesystem locate the data.
22. File descriptors
Now connect filesystem concepts to processes.
Suppose you run:
cat hello.txtThe process needs to open the file.
Linux gives the process a file descriptor.
A file descriptor is basically a number representing an open resource.
The standard ones are:
0 → stdin
1 → stdout
2 → stderrSo:
Process
│
├── 0 → stdin
├── 1 → stdout
└── 2 → stderrAnd when a process opens another file:
3 → hello.txtPotentially:
Process
│
├── 0 → stdin
├── 1 → stdout
├── 2 → stderr
└── 3 → hello.txt - cat processThis is why Linux calls many things file descriptors, not just regular files.
A descriptor can refer to things such as:
regular files
pipes
sockets
devicesWhat are 0, 1 and 2?
These are extremely important.
Every normal Linux process starts with three standard file descriptors.
FD 0 — stdin
0 → stdinStandard input.
It is where the program gets input.
Usually:
Keyboard
↓
stdin
↓
FD 0For example:
catIf you don’t give cat a filename, it waits for input.
FD 1 — stdout
1 → stdoutStandard output.
This is where normal output goes.
Usually:
Program
↓
stdout
↓
FD 1
↓
TerminalFor example:
echo helloConceptually:
echo
↓
stdout
↓
FD 1
↓
TerminalYou see:
helloon your screen.
FD 2 — stderr
2 → stderrStandard error.
This is where error messages normally go.
For example:
ls /does-not-existYou might see:
ls: cannot access '/does-not-exist': No such file or directoryThat message is sent through:
stderr
↓
FD 2
↓
Terminal23. Why does > work?
Now something you’ve probably used many times:
echo hello > file.txtThe > is shell redirection.
Conceptually:
echo
↓
stdout
↓
shell redirects stdout
↓
file.txtRemember:
1 = stdoutSo:
echo hello > file.txtis basically telling the shell:
“Take standard output and send it to this file.”
This is why understanding file descriptors is so useful.
24. Hard links
Now we can understand another interesting filesystem concept.
Suppose:
touch file1Then:
ln file1 file2Now:
file1
│
▼
inode 12345
│
▼
data
file2
│
└────→ same inodeBoth names point to the same inode.
So:
file1 ──┐
├──→ inode → data
file2 ──┘That’s a hard link.
25. Symbolic links
Now:
ln -s file1 file2creates a symbolic link.
Conceptually:
file2
│
▼
"file1"
│
▼
inode
│
▼
dataSo a symbolic link is more like a reference/path to another file.
This is why you often see:
something -> /some/pathwhen running:
ls -l26. Mount points — VERY important for DevOps
Now let’s connect the filesystem to actual disks.
Linux can have multiple filesystems:
SSD
│
├── Partition 1 → filesystem
└── Partition 2 → filesystemBut Linux presents them as one directory tree.
For example:
/
├── etc
├── home
├── var
└── dataSuppose /data is actually another filesystem.
Then:
/
│
├── etc
├── home
├── var
│
└── data
↑
│
mounted filesystemThis is called a mount point.







