Why do special device files have inodes?

The short answer is that it does only if you have a physical filesystem backing /dev (and if you're using a modern Linux distro, you probably don't).

The long answer follows:

This all goes back to the original UNIX philosophy that everything is a file. This philosophy is part of what made UNIX so versatile, because you could directly interact with devices from userspace without needing to have special code in your application to talk directly to the physical hardware.

Originally, /dev was just another directory with a well-known name where you put your device files. Some UNIX systems still take this approach (I believe OpenBSD still does), and you can usually tell if a system is like this because it will have lots of device files for devices the system doesn't actually have (for example, files for every possible partition on every possible disk). This saves space in memory and time at boot at the cost of using a bit more disk space, which was a good trade off for early systems because they were generally very memory constrained and not very fast. This is generally referred to as having a static /dev.

On modern Linux systems (and I believe also FreeBSD and possibly recent versions of Solaris), /dev is a temporary in-memory filesystem populated by the kernel (or udev if you use Systemd, because they don't trust the kernel to do almost anything). This saves some disk space at the price of some memory (usually less than a few MB) and a very small processing overhead. It also has a number of other advantages, with one of the biggest being that it's easier to detect hot-plugged hardware. This is generally referred to as having a dynamic /dev.

In both cases though, device nodes are accessed through the regular VFS layer, which by definition means they have to have an inode (even if it's a virtual one that just exists so that stuff like stat() works like it's supposed to. From a practical perspective, this has zero impact on systems that use a dynamic /dev because they just store the inodes in memory or generate them as needed, and near zero impact where /dev is static because inodes take up near zero space on-disk and most filesystems either have no upper limit on them or provision way more than anybody is likely to ever need.


Device files have permissions, too, and those are stored in an inode.


Directories are simply a mapping from filenames to inodes, so everything about the thing that the name refers to (a file, a symlink, a device, a FIFO, a socket) has to be in the inode, there's nowhere else to put it.

Information about the device is stored in the inode. The major and minor device numbers are there, so are permissions, timestamps, etc. The type field that says that it's a block or character device rather than a regular file is stored there.

The inode for devices simply doesn't make use of the fields that contain the block map of the file.