mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 11:03:07 -04:00
Merge patch series "iomap/fuse: add helper to keep uptodate bitmap in sync"
Joanne Koong <joannelkoong@gmail.com> says: iomap/fuse: add helper to keep uptodate bitmap in sync Filesystems that use iomap normally mark folios uptodate through the iomap read/write paths, which keep iomap's internal uptodate bitmap in sync. However, some filesystems need to write data directly into the page cache outside of those paths (eg fuse, which may need to write server-pushed data straight into the page cache for servicing notify stores). These filesystems need a way to mark a folio uptodate that also updates the iomap bitmap so they're kept in sync. This series adds iomap_folio_mark_uptodate() for filesystems to do that and updates the relevant fuse call paths to use this. This is needed before fuse can enable large folios. Patch 1 ("fuse: don't clear folio uptodate on writethrough errors") was originally submitted to the fuse tree [1] but patch 3 ("fuse: use iomap helper to mark folio uptodate") has a dependency on it, so to make cross-coordination between trees easier, patch 1 is now part of this series and submitted to the vfs tree. [1] https://lore.kernel.org/fuse-devel/20260624205201.842714-1-joannelkoong@gmail.com/ * patches from https://patch.msgid.link/20260707220450.1200943-1-joannelkoong@gmail.com: fuse: use iomap helper to mark folio uptodate iomap: add helper to mark folio uptodate fuse: don't clear folio uptodate on writethrough errors Link: https://patch.msgid.link/20260707220450.1200943-1-joannelkoong@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
@@ -1227,8 +1227,7 @@ static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct fuse_file *ff = file->private_data;
|
||||
struct fuse_mount *fm = ff->fm;
|
||||
unsigned int offset, i;
|
||||
bool short_write;
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < ap->num_folios; i++)
|
||||
@@ -1243,24 +1242,9 @@ static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
|
||||
if (!err && ia->write.out.size > count)
|
||||
err = -EIO;
|
||||
|
||||
short_write = ia->write.out.size < count;
|
||||
offset = ap->descs[0].offset;
|
||||
count = ia->write.out.size;
|
||||
for (i = 0; i < ap->num_folios; i++) {
|
||||
struct folio *folio = ap->folios[i];
|
||||
|
||||
if (err) {
|
||||
folio_clear_uptodate(folio);
|
||||
} else {
|
||||
if (count >= folio_size(folio) - offset)
|
||||
count -= folio_size(folio) - offset;
|
||||
else {
|
||||
if (short_write)
|
||||
folio_clear_uptodate(folio);
|
||||
count = 0;
|
||||
}
|
||||
offset = 0;
|
||||
}
|
||||
if (ia->write.folio_locked && (i == ap->num_folios - 1))
|
||||
folio_unlock(folio);
|
||||
folio_put(folio);
|
||||
@@ -1335,7 +1319,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
|
||||
|
||||
/* If we copied full folio, mark it uptodate */
|
||||
if (tmp == folio_size(folio))
|
||||
folio_mark_uptodate(folio);
|
||||
iomap_folio_mark_uptodate(folio);
|
||||
|
||||
if (folio_test_uptodate(folio)) {
|
||||
folio_unlock(folio);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "dev.h"
|
||||
#include "fuse_i.h"
|
||||
|
||||
#include <linux/iomap.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
||||
static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
|
||||
@@ -192,7 +194,7 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
|
||||
if (!folio_test_uptodate(folio) && !err && folio_offset == 0 &&
|
||||
(nr_bytes == folio_size(folio) || file_size == end)) {
|
||||
folio_zero_segment(folio, nr_bytes, folio_size(folio));
|
||||
folio_mark_uptodate(folio);
|
||||
iomap_folio_mark_uptodate(folio);
|
||||
}
|
||||
folio_unlock(folio);
|
||||
folio_put(folio);
|
||||
|
||||
@@ -105,6 +105,12 @@ static void iomap_set_range_uptodate(struct folio *folio, size_t off,
|
||||
folio_mark_uptodate(folio);
|
||||
}
|
||||
|
||||
void iomap_folio_mark_uptodate(struct folio *folio)
|
||||
{
|
||||
iomap_set_range_uptodate(folio, 0, folio_size(folio));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iomap_folio_mark_uptodate);
|
||||
|
||||
/*
|
||||
* Find the next dirty block in the folio. end_blk is inclusive.
|
||||
* If no dirty block is found, this will return end_blk + 1.
|
||||
|
||||
@@ -365,6 +365,7 @@ struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos, size_t len);
|
||||
bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags);
|
||||
void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len);
|
||||
bool iomap_dirty_folio(struct address_space *mapping, struct folio *folio);
|
||||
void iomap_folio_mark_uptodate(struct folio *folio);
|
||||
int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
|
||||
const struct iomap_ops *ops,
|
||||
const struct iomap_write_ops *write_ops);
|
||||
|
||||
Reference in New Issue
Block a user