[PATCH 10/16] fuse2fs: flush and invalidate the buffer cache on trim

Darrick J. Wong
2025-05-22T00:13:28Z

Discard operates directly on the storage device, which means that we
need to flush and invalidate the buffer cache because it could be
caching freed blocks whose contents are about to change.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
misc/fuse2fs.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index 7152979ed6694e..219d4bf698d628 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -4365,6 +4365,11 @@ static int ioctl_fitrim(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
cleared = 0;
max_blocks = FUSE2FS_B_TO_FSBT(ff, 2048ULL * 1024 * 1024);

+ /* flush any dirty data out of the disk cache before trimming */
+ err = io_channel_flush_tag(ff->fs->io, IO_CHANNEL_TAG_NULL);
+ if (err)
+ return translate_error(fs, fh->ino, err);
+
fr->len = 0;
while (start <= end) {
err = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
@@ -4394,6 +4399,16 @@ static int ioctl_fitrim(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
}
start = b + 1;
}
+ if (err)
+ goto out;
+
+ /*
+ * Invalidate the entire disk cache now that we've written zeroes so
+ * that EXT2_ALLOCRANGE_ZERO_BLOCKS works correctly.
+ */
+ err = io_channel_invalidate_tag(ff->fs->io, IO_CHANNEL_TAG_NULL);
+ if (err)
+ return translate_error(fs, fh->ino, err);

out:
fr->len = cleared;