From: Darrick J. Wong <djwong@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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;