#Linux

10 articles

The Block Layer

The Block Layer

In the previous article we followed a read() all the way down through the VFS: from the syscall, to the struct file, to ext4, and into the page cache. And there was exactly one moment where we skipped over the details. When the page cache missed — the bytes weren’t in memory yet — the filesystem had to actually go and fetch them, and all we said was that it “reads the disk, through the block layer.” That’s the moment we’re going to open up now.

The VFS

The VFS

In the previous article we saw how the scheduler decides which task gets the CPU — so at this point we know how programs get to run. But running isn’t enough: for a program to be useful, it almost always needs to read and store data — its config from /etc, a shared library from /usr/lib, the rows of a database file, the document you’re saving. So the natural next question is: what actually happens when a program opens a file?

The Scheduler

The Scheduler

In the previous article we looked at how the kernel gives every process its own private view of memory. But memory is only half of what a process needs to actually run. The other half is the CPU itself — and there are only so many CPUs in a machine, while there are usually hundreds or thousands of things that want to run on them.

So somebody has to decide, constantly, who gets a CPU and for how long. That somebody is the scheduler. Every few milliseconds, on every core, the kernel asks itself the same question — of everything that wants to run right now, who runs next? — and the answer has to be fast, fair, and good enough that your text editor stays responsive even while a compile is pegging every core.

Memory Manager

Memory Manager

In the previous article we looked at how a user program crosses the ring 3 → ring 0 boundary to ask the kernel for help. The example we used was read() — a file descriptor, a buffer pointer, a byte count. But we glossed over something important: what is that buffer? Who decided it existed? Who owns the physical RAM behind it?

Those questions are what the memory manager answers. And it answers them for every process on the machine, simultaneously, for every allocation that has ever happened since boot. It’s one of the most complex subsystems in the kernel, so I want to approach it the way you’d approach an unfamiliar library — start at the front desk with the catalog, then walk back through the stacks.

System Calls

System Calls

In the previous article we followed the kernel from the very first instruction the bootloader handed us all the way to the moment kernel_init called execve() on /sbin/init. That was a long ride, but it ended with a quiet handover: the kernel stepped aside, userspace took the wheel, and /sbin/init started spawning the rest of the services.

Here’s the thing though. Those processes that just started don’t actually have keys to anything. They can’t touch the disk. They can’t talk to the network card. They can’t even draw a pixel on the screen. Every piece of hardware in the machine is still owned by the kernel, and the CPU itself enforces this: user programs run in a restricted execution mode (ring 3 — the unprivileged mode where hardware blocks direct access to kernel memory or devices). Userspace is sandboxed by hardware, on purpose.

The Linux Kernel Startup

The Linux Kernel Startup

Have you ever wondered what really happens between the moment you press the power button and the moment your login screen shows up? That gap—usually some seconds—hides one of the most intricate initialization sequences in computing. Today I want to walk you through it.

This is the first article in a series where I’ll try to make sense of the Linux kernel internals together with you. We’ll talk about how Linux boots, how it manages processes and memory, how it deals with hardware, and so on. If you’ve ever been curious about what’s happening under the hood, you’re in the right place.

ZFS

ZFS

In the previous article , we explored Btrfs—a copy-on-write filesystem built around a single kind of B-tree, where every file, extent, checksum and chunk mapping lives as a tagged item in some tree, and snapshots fall out of the reference-counted extent design. Btrfs took a lot of inspiration from an older system that pioneered most of these ideas: ZFS.

ZFS started life at Sun Microsystems in the mid-2000s and now lives on as OpenZFS, ported to Linux, FreeBSD, illumos, and macOS. From the outside it solves the same problems as Btrfs—pooled storage, copy-on-write, snapshots, checksums, integrated RAID—but the shape underneath is genuinely different. Where Btrfs leaned on one universal B-tree node format and a single key shape, ZFS leans on something else entirely: a 128-byte block pointer that fully describes the block it points to, and a strict three-layer architecture stacked on top of it.

Btrfs

Btrfs

In the previous article , we explored XFS—a filesystem built for extreme scale that divides the disk into independent Allocation Groups, each with its own B+ trees for free space, inodes, and extent tracking. XFS, like every filesystem we’ve covered in this series, shares one fundamental characteristic with ext4, NTFS, and FAT32: it modifies data in place. When you update a block, the new data overwrites the old data at the same disk location.

XFS

XFS

In the previous article , we explored NTFS—a filesystem where everything is a file, from your documents to the Master File Table itself. NTFS centralized all metadata into the MFT, using attribute-based records and a single journal to keep Windows volumes consistent and feature-rich.

Now let me introduce you to XFS, the filesystem designed for extreme scale. Originally built by Silicon Graphics in 1993 for their high-end IRIX workstations, XFS was engineered to handle filesystems measured in terabytes when most systems still counted in megabytes. Its core idea is to divide the disk into independent regions called Allocation Groups—each with its own free space tracking, its own inode management, and its own locks. This simple design choice is what allows XFS to scale linearly with the number of CPU cores and support filesystems up to 8 exabytes.

Ext4

Ext4

In the previous article , we explored FAT32—a filesystem that conquered the world through simplicity. Its linked-list approach gets the job done, but it comes with real limitations: no crash protection, linear directory searches that slow down as directories grow, and a hard 4GB ceiling on file sizes.

Ext4 takes a fundamentally different approach. Where FAT32 uses a single table as both its allocation tracker and file map, ext4 divides the disk into block groups, each with its own dedicated structures for tracking free space and storing file metadata. Where FAT32 walks a linked list to find your data, ext4 uses extents—a compact B-tree where each entry describes a contiguous run of blocks. And where FAT32 has no crash protection at all, ext4 uses journaling to ensure your filesystem stays consistent after unexpected shutdowns.