Sitemap
Oshadhi Wickramasinghe

Oshadhi Wickramasinghe

Writing about DevOps, AWS, Kubernetes, Terraform, GitOps, CI/CD, monitoring, automation, and lessons from production environments.

Linux Filesystems — Deep Dive

9 min readAug 27, 2026

--

Before learning commands like:

df -h
du -sh
ls -i
mount
find

we 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 GB

But an SSD by itself doesn’t understand concepts like:

/home/user/file.txt
/var/log/app.log
/etc/nginx/nginx.conf

Something 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
Btrfs

So think of the layers like this:

Application
↓
Linux system calls
↓
Filesystem
↓
Block device
↓
Storage driver
↓
SSD

For example:

cat /home/user/file.txt

eventually 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 SSD

That’s the physical storage device.

You could partition it:

SSD
│
├── Partition 1
│
├── Partition 2
│
└── Partition 3

Then put filesystems on those partitions:

SSD
│
├── Partition 1
│ └── ext4 filesystem
│
├── Partition 2
│ └── XFS filesystem
│
└── Partition 3
└── ext4 filesystem

So:

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
└── sys

Compare 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 model

4. /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/hosts

or:

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/log

If 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:

ls

versus:

ls -la

8. /usr

This one confuses many beginners.

People sometimes think:

“usr means 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 software

For example:

/usr/bin
/usr/sbin
/usr/lib
/usr/share

What is /usr/bin?

This is probably the easiest part.

Try:

ls /usr/bin

You’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:

ls

you are actually running a program.

You can find where it is:

which ls

You may get:

/usr/bin/ls

So:

You type:

ls
↓
Shell finds:
↓
/usr/bin/ls
↓
Operating system executes it

This connects directly to what we learned about processes.

Conceptually:

/usr/bin/ls
│
│ execute
▼
Process
│
▼
CPU

So /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

bin traditionally contains general-purpose executables, while sbin traditionally contains system-administration executables.

9. /tmp

Think:

temporary files

Applications can use:

/tmp

for temporary data.

For example:

echo "hello" > /tmp/test.txt

Then:

cat /tmp/test.txt

You might see:

hello

Don’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 /dev

You may see things like:

/dev/null
/dev/random
/dev/zero
/dev/sda
/dev/nvme0n1

But 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/null

You won’t see:

hello

Where did it go?

Nowhere useful.

/dev/null is a special device that discards data written to it.

Conceptually:

Program
↓
/dev/null
↓
Data disappears

That’s why you’ll often see:

command > /dev/null

12. /dev/zero

Another interesting one:

/dev/zero

Reading from it produces zero bytes.

For example:

head -c 10 /dev/zero

It provides zero-valued bytes.

Again:

/dev/zero

isn'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/sda

Historically, Linux uses names such as:

/dev/sda
/dev/sdb
/dev/sdc

for disks.

Think:

/dev/sda  → first disk
/dev/sdb → second disk
/dev/sdc → third disk

For example:

Computer
│
├── Disk 1 → /dev/sda
├── Disk 2 → /dev/sdb
└── Disk 3 → /dev/sdc

What about /dev/sda1?

Now we add a number:

/dev/sda1
↑
partition 1

So:

/dev/sda - Disk 1
│
├── /dev/sda1 - Disk1, Partition 1
├── /dev/sda2 - Disk1, Partition 2
└── /dev/sda3 - Disk1, Partition 3

On NVMe systems:

/dev/nvme0n1

These can represent storage devices.

For example:

/dev/nvme0n1

might 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 device

So:

/dev/nvme0n1

means approximately:

NVMe controller 0, namespace 1

Then partitions could appear as:

/dev/nvme0n1p1
/dev/nvme0n1p2
/dev/nvme0n1p3

Conceptually:

SSD
│
└── /dev/nvme0n1 - Your NVMe storage device
│
├── /dev/nvme0n1p1 - Partition 1
├── /dev/nvme0n1p2 - Partition 2
└── /dev/nvme0n1p3 - Partition 3

You can inspect this with:

lsblk

NVMe 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 Memory

SSD = 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 /proc

You’ll see things like:

1
2
3
...
cpuinfo
meminfo
uptime
version

You 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 state

15. /proc/1

Let’s say:

PID 1 = systemd

You can run:

cat /proc/1/status

You’re essentially asking the kernel:

“Give me information about process 1.”

You may see information about:

Name
State
Pid
PPid
Uid
Gid
memory
threads

This is a beautiful connection:

Process
↓
PID 1
↓
/proc/1/
↓
Kernel exposes process information

16. /proc/meminfo

Remember our memory lesson?

We used:

free -h

Where does a lot of that information ultimately come from?

Try:

cat /proc/meminfo

You’ll see:

MemTotal
MemFree
MemAvailable
Buffers
Cached
SwapTotal
SwapFree
...

So:

free -h
↓
kernel memory information
↓
/proc/meminfo

Now our filesystem lesson connects to our memory lesson.

17. /proc/cpuinfo

Similarly:

cat /proc/cpuinfo

can expose CPU information.

Again:

/proc

is giving you a window into the kernel’s view of the system.

18. /sys — Another virtual filesystem

Now:

/sys

is 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
lo

or:

ens33
lo

These represent network interfaces.

So we can remember:

/proc → processes + kernel/system information

/sys → devices + drivers + hardware model

19. Now let’s understand INODES

This is one of the most important filesystem concepts.

Suppose you create:

touch hello.txt

You might think Linux stores:

hello.txt
↓
data

But 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 blocks

You can see inode numbers with:

ls -i

For example:

123456 hello.txt

Here:

123456

is the inode number.

20. Filename vs inode

This distinction is VERY important.

Think:

Filename
↓
inode
↓
file metadata
↓
data blocks

The filename is essentially an entry in a directory that points to an inode.

So:

hello.txt
│
▼
inode 123456
│
├── permissions
├── owner
├── size
└── data block references

This understanding makes hard links much easier later.

21. File data is stored in blocks

Suppose:

hello.txt

contains:

Hello Linux!

The filesystem stores the actual data in storage blocks.

Conceptually:

hello.txt
↓
inode
↓
data blocks
↓
SSD

The inode helps the filesystem locate the data.

22. File descriptors

Now connect filesystem concepts to processes.

Suppose you run:

cat hello.txt

The 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 → stderr

So:

Process
│
├── 0 → stdin
├── 1 → stdout
└── 2 → stderr

And when a process opens another file:

3 → hello.txt

Potentially:

Process
│
├── 0 → stdin
├── 1 → stdout
├── 2 → stderr
└── 3 → hello.txt - cat process

This is why Linux calls many things file descriptors, not just regular files.

A descriptor can refer to things such as:

regular files
pipes
sockets
devices

What are 0, 1 and 2?

These are extremely important.

Every normal Linux process starts with three standard file descriptors.

FD 0 — stdin

0 → stdin

Standard input.

It is where the program gets input.

Usually:

Keyboard
↓
stdin
↓
FD 0

For example:

cat

If you don’t give cat a filename, it waits for input.

FD 1 — stdout

1 → stdout

Standard output.

This is where normal output goes.

Usually:

Program
↓
stdout
↓
FD 1
↓
Terminal

For example:

echo hello

Conceptually:

echo
↓
stdout
↓
FD 1
↓
Terminal

You see:

hello

on your screen.

FD 2 — stderr

2 → stderr

Standard error.

This is where error messages normally go.

For example:

ls /does-not-exist

You might see:

ls: cannot access '/does-not-exist': No such file or directory

That message is sent through:

stderr
↓
FD 2
↓
Terminal

23. Why does > work?

Now something you’ve probably used many times:

echo hello > file.txt

The > is shell redirection.

Conceptually:

echo
↓
stdout
↓
shell redirects stdout
↓
file.txt

Remember:

1 = stdout

So:

echo hello > file.txt

is 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 file1

Then:

ln file1 file2

Now:

file1
│
▼
inode 12345
│
▼
data

file2
│
└────→ same inode

Both names point to the same inode.

So:

file1 ──┐
├──→ inode → data
file2 ──┘

That’s a hard link.

25. Symbolic links

Now:

ln -s file1 file2

creates a symbolic link.

Conceptually:

file2
│
▼
"file1"
│
▼
inode
│
▼
data

So a symbolic link is more like a reference/path to another file.

This is why you often see:

something -> /some/path

when running:

ls -l

26. 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 → filesystem

But Linux presents them as one directory tree.

For example:

/
├── etc
├── home
├── var
└── data

Suppose /data is actually another filesystem.

Then:

/
│
├── etc
├── home
├── var
│
└── data
↑
│
mounted filesystem

This is called a mount point.

Press enter or click to view image in full size

--

--

Oshadhi Wickramasinghe

Written by Oshadhi Wickramasinghe

Writing about DevOps, AWS, Kubernetes, Terraform, GitOps, CI/CD, monitoring, automation, and lessons from production environments.