The Linux kernel's iomap layer

chmaynard1 pts0 comments

The kernel's iomap layer [LWN.net]

LWN<br>.net<br>News from the source

Content Weekly Edition<br>Archives<br>Search<br>Kernel<br>Security<br>Events calendar<br>Unread comments

LWN FAQ<br>Write for us

User:<br>Password: |

Log in /<br>Subscribe /<br>Register

The kernel's iomap layer

[LWN subscriber-only content]

Welcome to LWN.net

The following subscription-only content has been made available to you<br>by an LWN subscriber. Thousands of subscribers depend on LWN for the<br>best news from the Linux and free software communities. If you enjoy this<br>article, please consider accepting the discount offer on the right. Thank you<br>for visiting LWN.net!

Special discount offer

Subscribe to LWN now at the<br>"professional hacker" level for at least six months,<br>and you will<br>receive a special discount of 25%.

By Jonathan Corbet<br>July 6, 2026

Conversations about the kernel's filesystem implementations often involve a<br>layer called "iomap", but relatively few people can reliably say what iomap<br>actually is. That is just the kind of gap that LWN exists to fill. In<br>short, iomap handles the mapping between data in the filesystem space<br>(identified by a file of interest, and an offset within that file) and in<br>the storage space (which may be a memory location, or a set of blocks on a<br>storage device). Using that mapping, iomap handles a long list of common,<br>filesystem-related tasks, allowing a lot of boilerplate code to be removed<br>from individual filesystem implementations.

The iomap code was first introduced as such by<br>Christoph Hellwig for the 4.8 kernel release in late 2016, but much of that<br>functionality was based on an earlier implementation by Dave<br>Chinner in the XFS filesystem. It has grown over the years as filesystems<br>have been converted over and new functionality has been added. The current<br>implementation consists of a dozen files in the fs/iomap<br>directory. It is implemented as two broad layers, a low-level mapping<br>between files and their backing store, which is used by higher-level code<br>to implement much of the functionality that a filesystem needs.

The storage mapping

Every file implemented by a filesystem, with few exceptions, is a<br>representation of a series of bytes stored on a persistent medium somewhere.<br>Much of the work a filesystem does comes down implementing operations<br>expressed in terms of files and offsets by moving data between memory and<br>that persistent media. A key part of this task is managing the mapping<br>between those two domains.

In the earlier days of Linux, this mapping was represented by buffer heads, but they suffer from a number of<br>problems. As a direct mapping between a disk block and an equally sized<br>region of memory, buffer heads are not designed for today's large files and<br>extent-based filesystems. It is difficult to generate large, efficient<br>I/O operations when the data involved is<br>represented by buffer heads. A single contiguous extent on disk might<br>require hundreds of buffer heads, each managing a single block, which must<br>be reassembled into a small number of I/O<br>operations.

With iomap, a mapping that might have involved a large number of buffer<br>heads can, instead, be expressed with a single iomap<br>structure:

struct iomap {<br>u64 addr; /* disk offset of mapping, bytes */<br>loff_t offset; /* file offset of mapping, bytes */<br>u64 length; /* length of mapping, bytes */<br>u16 type; /* type of mapping */<br>u16 flags; /* flags for mapping */<br>struct block_device *bdev; /* block device for I/O */<br>struct dax_device *dax_dev; /* dax_dev for dax operations */<br>void *inline_data;<br>void *private; /* filesystem private */<br>u64 validity_cookie; /* used with .iomap_valid() */<br>};

To simplify things a bit, an instance of this structure says that the range<br>of a file starting at offset bytes and continuing for<br>length bytes is stored at addr on the underlying device<br>which, in turn, is identified by bdev (for normal block devices),<br>dax_dev (for persistent-memory DAX devices), or the memory range at<br>inline_data. The type field describes what kind of<br>mapping is actually represented:

IOMAP_MAPPED indicates a normal mapping from the file to<br>space on the persistent storage device.<br>IOMAP_INLINE, instead, is a mapping between the file and<br>the memory pointed to by inline_data. This sort of mapping<br>might be used for tiny files where the file data can be stored in the<br>file inode itself.<br>IOMAP_HOLE means that the underlying storage has not been<br>allocated — that there is no mapping at all. It is only valid for<br>read operations, and the result is that a read from this range will<br>return zeroes.<br>IOMAP_DELALLOC also says that the mapping does not exist, but<br>that it will be created at a future time.<br>IOMAP_UNWRITTEN says that the mapping exists, but that the<br>backing store has not been written and may contain random (or<br>sensitive) data. Reads from this range will return zeros rather than<br>going to the backing store.

There is an<br>extensive set of flags that can be set by the filesystem to<br>affect how the I/O is done, mark a shared<br>mapping that must be copied on write, and...

mapping iomap filesystem file from kernel

Related Articles