Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions Documentation/filesystems/iomap/operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,28 @@ These ``struct kiocb`` flags are significant for buffered I/O with iomap:

* ``IOCB_DONTCACHE``: Turns on ``IOMAP_DONTCACHE``.

``struct iomap_read_ops``
--------------------------

.. code-block:: c

struct iomap_read_ops {
int (*read_folio_range)(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx, size_t len);
void (*submit_read)(struct iomap_read_folio_ctx *ctx);
};

iomap calls these functions:

- ``read_folio_range``: Called to read in the range. This must be provided
by the caller. The caller is responsible for calling
iomap_finish_folio_read() after reading in the folio range. This should be
done even if an error is encountered during the read. This returns 0 on
success or a negative error on failure.

- ``submit_read``: Submit any pending read requests. This function is
optional.

Internal per-Folio State
------------------------

Expand Down Expand Up @@ -182,6 +204,28 @@ The ``flags`` argument to ``->iomap_begin`` will be set to zero.
The pagecache takes whatever locks it needs before calling the
filesystem.

Both ``iomap_readahead`` and ``iomap_read_folio`` pass in a ``struct
iomap_read_folio_ctx``:

.. code-block:: c

struct iomap_read_folio_ctx {
const struct iomap_read_ops *ops;
struct folio *cur_folio;
struct readahead_control *rac;
void *read_ctx;
};

``iomap_readahead`` must set:
* ``ops->read_folio_range()`` and ``rac``

``iomap_read_folio`` must set:
* ``ops->read_folio_range()`` and ``cur_folio``

``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs accessible in the ops callbacks for
fulfilling reads.
Comment on lines +225 to +227

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (typo): Slight grammar improvement around "needs accessible".

Rephrase to "any custom data the caller needs to be accessible in the ops callbacks" for smoother grammar.

Suggested change
``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs accessible in the ops callbacks for
fulfilling reads.
``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs to be accessible in the ops callbacks
for fulfilling reads.


Buffered Writes
---------------

Expand Down
5 changes: 3 additions & 2 deletions block/fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,12 +540,13 @@ const struct address_space_operations def_blk_aops = {
#else /* CONFIG_BUFFER_HEAD */
static int blkdev_read_folio(struct file *file, struct folio *folio)
{
return iomap_read_folio(folio, &blkdev_iomap_ops);
iomap_bio_read_folio(folio, &blkdev_iomap_ops);
return 0;
}

static void blkdev_readahead(struct readahead_control *rac)
{
iomap_readahead(rac, &blkdev_iomap_ops);
iomap_bio_readahead(rac, &blkdev_iomap_ops);
}

static ssize_t blkdev_writeback_range(struct iomap_writepage_ctx *wpc,
Expand Down
30 changes: 12 additions & 18 deletions fs/dax.c
Original file line number Diff line number Diff line change
Expand Up @@ -1507,7 +1507,7 @@ static int dax_zero_iter(struct iomap_iter *iter, bool *did_zero)

/* already zeroed? we're done. */
if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN)
return iomap_iter_advance(iter, &length);
return iomap_iter_advance(iter, length);

/*
* invalidate the pages whose sharing state is to be changed
Expand Down Expand Up @@ -1536,10 +1536,10 @@ static int dax_zero_iter(struct iomap_iter *iter, bool *did_zero)
if (ret < 0)
return ret;

ret = iomap_iter_advance(iter, &length);
ret = iomap_iter_advance(iter, length);
if (ret)
return ret;
} while (length > 0);
} while ((length = iomap_length(iter)) > 0);

if (did_zero)
*did_zero = true;
Expand Down Expand Up @@ -1597,7 +1597,7 @@ static int dax_iomap_iter(struct iomap_iter *iomi, struct iov_iter *iter)

if (iomap->type == IOMAP_HOLE || iomap->type == IOMAP_UNWRITTEN) {
done = iov_iter_zero(min(length, end - pos), iter);
return iomap_iter_advance(iomi, &done);
return iomap_iter_advance(iomi, done);
}
}

Expand Down Expand Up @@ -1681,12 +1681,12 @@ static int dax_iomap_iter(struct iomap_iter *iomi, struct iov_iter *iter)
xfer = dax_copy_to_iter(dax_dev, pgoff, kaddr,
map_len, iter);

length = xfer;
ret = iomap_iter_advance(iomi, &length);
ret = iomap_iter_advance(iomi, xfer);
if (!ret && xfer == 0)
ret = -EFAULT;
if (xfer < map_len)
break;
length = iomap_length(iomi);
}
dax_read_unlock(id);

Expand Down Expand Up @@ -1919,10 +1919,8 @@ static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, unsigned long *pfnp,
ret |= VM_FAULT_MAJOR;
}

if (!(ret & VM_FAULT_ERROR)) {
u64 length = PAGE_SIZE;
iter.status = iomap_iter_advance(&iter, &length);
}
if (!(ret & VM_FAULT_ERROR))
iter.status = iomap_iter_advance(&iter, PAGE_SIZE);
}

if (iomap_errp)
Expand Down Expand Up @@ -2034,10 +2032,8 @@ static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, unsigned long *pfnp,
continue; /* actually breaks out of the loop */

ret = dax_fault_iter(vmf, &iter, pfnp, &xas, &entry, true);
if (ret != VM_FAULT_FALLBACK) {
u64 length = PMD_SIZE;
iter.status = iomap_iter_advance(&iter, &length);
}
if (ret != VM_FAULT_FALLBACK)
iter.status = iomap_iter_advance(&iter, PMD_SIZE);
}

unlock_entry:
Expand Down Expand Up @@ -2163,7 +2159,6 @@ static int dax_range_compare_iter(struct iomap_iter *it_src,
const struct iomap *smap = &it_src->iomap;
const struct iomap *dmap = &it_dest->iomap;
loff_t pos1 = it_src->pos, pos2 = it_dest->pos;
u64 dest_len;
void *saddr, *daddr;
int id, ret;

Expand Down Expand Up @@ -2196,10 +2191,9 @@ static int dax_range_compare_iter(struct iomap_iter *it_src,
dax_read_unlock(id);

advance:
dest_len = len;
ret = iomap_iter_advance(it_src, &len);
ret = iomap_iter_advance(it_src, len);
if (!ret)
ret = iomap_iter_advance(it_dest, &dest_len);
ret = iomap_iter_advance(it_dest, len);
return ret;

out_unlock:
Expand Down
5 changes: 3 additions & 2 deletions fs/erofs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,16 @@ static int erofs_read_folio(struct file *file, struct folio *folio)
{
trace_erofs_read_folio(folio, true);

return iomap_read_folio(folio, &erofs_iomap_ops);
iomap_bio_read_folio(folio, &erofs_iomap_ops);
return 0;
}

static void erofs_readahead(struct readahead_control *rac)
{
trace_erofs_readahead(rac->mapping->host, readahead_index(rac),
readahead_count(rac), true);

return iomap_readahead(rac, &erofs_iomap_ops);
iomap_bio_readahead(rac, &erofs_iomap_ops);
}

static sector_t erofs_bmap(struct address_space *mapping, sector_t block)
Expand Down
2 changes: 1 addition & 1 deletion fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ static void fuse_fillattr(struct mnt_idmap *idmap, struct inode *inode,
if (attr->blksize != 0)
blkbits = ilog2(attr->blksize);
else
blkbits = fc->blkbits;
blkbits = inode->i_sb->s_blocksize_bits;

stat->blksize = 1 << blkbits;
}
Expand Down
Loading
Loading