Skip to main content
RunBook Academy

LinuxIII · Filesystems and FilesInodes

Inodes, dentries, and the VFS — how Linux tracks files

Foundation⏱ ~12 minbashlsstatdfdu

What you'll learn

  • Explain what an inode is and what it stores
  • Read inode numbers from `ls -i` and `stat`
  • Identify the inode exhaustion failure mode before it happens
  • Understand why `df` and `du` can disagree on the same filesystem

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

The filesystem path is for humans. The kernel does not look up files by path — it looks them up by inode number, an integer that uniquely identifies a file on a particular filesystem.

What an inode stores

Each file on disk has an inode. The inode holds everything the kernel needs to access the file except its name and its contents:

FieldWhat it stores
File kindRegular, directory, symlink, device, socket, pipe
PermissionsMode bits (rwx for owner/group/other)
OwnershipUID, GID
SizeLogical size in bytes
Timestampsatime, mtime, ctime (and on modern filesystems, btime)
Link countNumber of hard links pointing at this inode
Block pointersLocations of the data blocks on disk
Extended attributesxattrs, capability bits, ACLs

The path is not in the inode. The kernel maintains a separate structure (the dentry cache) that maps paths to inodes in memory.

Inspecting inodes

Read-only / Safels -li
$ ls -li /etc/passwd /etc/shadow /etc/group
12345 -rw-r--r-- 1 root root 3010 Aug  9 11:11 /etc/passwd
12346 -rw-r----- 1 root shadow 1840 Aug  9 11:11 /etc/shadow
12347 -rw-r--r-- 1 root root  1024 Aug  9 11:11 /etc/group

Illustrative output

The inode number is unique within a filesystem. The same inode number can appear on different filesystems and refer to different files.

Inode exhaustion

Every filesystem is created with a fixed number of inodes. A small file uses one inode; a large file uses one inode. The filesystem has a fixed pool regardless of file size.

This matters in production:

Read-only / Safeinode exhaustion
$ df -i /var
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sdc1      6553600 6549870   3730  100% /var

Illustrative output

Why df and du disagree

The classic production question: df says the filesystem is full, but du on every directory adds up to half the size. What is missing?

ToolWhat it measures
dfTotal blocks allocated to the filesystem’s free-space bitmap, including blocks held by open-but-deleted files
duBytes accounted for by walking the directory tree from a starting point

The gap is almost always deleted-but-open files. A process holds a file descriptor open after the file has been unlinked; the file’s inode is preserved (because the link count never hit zero) and its blocks are not freed; but the file no longer appears in any directory, so du does not see it.

Read-only / Safedeleted-but-open
$ lsof +L1 | head
COMMAND   PID  USER   FD   TYPE DEVICE    SIZE/OFF NLINK  NODE NAME
mysqld   1234 mysql   42u   REG  253,1 5242880000     0  67890 /var/lib/mysql/ibdata1 (deleted)
logrotat  5678 root    4w   REG  253,1  104857600     0  34567 /var/log/nginx/access.log (deleted)

Illustrative output

The remediation: restart or signal the holding process (often after rotating logs without copytruncate), or use fuser / lsof to identify the process holding the file and decide whether the file-descriptor leak is real.

Knowledge check

Knowledge check · 3 questions

  1. Q1. Which piece of file metadata does an inode store?

  2. Q2. A write can fail with ENOSPC while df -h still shows the filesystem is nearly empty.

  3. Q3. Which of the following would cause `df` to report the filesystem as more full than `du` suggests? Select all that apply.

Passing score: 75%. Answers are checked in this browser.