54 lines
2.0 KiB
Diff
54 lines
2.0 KiB
Diff
From 2435722a492f57a060202726a820b0da64f42105 Mon Sep 17 00:00:00 2001
|
|
From: Jan Kara <jack@suse.cz>
|
|
Date: Wed, 30 Jul 2025 12:28:41 +0200
|
|
Subject: iomap: Fix broken data integrity guarantees for O_SYNC writes
|
|
|
|
Commit d279c80e0bac ("iomap: inline iomap_dio_bio_opflags()") has broken
|
|
the logic in iomap_dio_bio_iter() in a way that when the device does
|
|
support FUA (or has no writeback cache) and the direct IO happens to
|
|
freshly allocated or unwritten extents, we will *not* issue fsync after
|
|
completing direct IO O_SYNC / O_DSYNC write because the
|
|
IOMAP_DIO_WRITE_THROUGH flag stays mistakenly set. Fix the problem by
|
|
clearing IOMAP_DIO_WRITE_THROUGH whenever we do not perform FUA write as
|
|
it was originally intended.
|
|
|
|
CC: John Garry <john.g.garry@oracle.com>
|
|
CC: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
|
|
Fixes: d279c80e0bac ("iomap: inline iomap_dio_bio_opflags()")
|
|
CC: stable@vger.kernel.org
|
|
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
Link: https://lore.kernel.org/20250730102840.20470-2-jack@suse.cz
|
|
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
|
|
Reviewed-by: John Garry <john.g.garry@oracle.com>
|
|
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
|
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
|
Signed-off-by: Christian Brauner <brauner@kernel.org>
|
|
---
|
|
fs/iomap/direct-io.c | 14 +++++++-------
|
|
1 file changed, 7 insertions(+), 7 deletions(-)
|
|
|
|
--- a/fs/iomap/direct-io.c
|
|
+++ b/fs/iomap/direct-io.c
|
|
@@ -368,14 +368,14 @@ static int iomap_dio_bio_iter(struct iom
|
|
if (iomap->flags & IOMAP_F_SHARED)
|
|
dio->flags |= IOMAP_DIO_COW;
|
|
|
|
- if (iomap->flags & IOMAP_F_NEW) {
|
|
+ if (iomap->flags & IOMAP_F_NEW)
|
|
need_zeroout = true;
|
|
- } else if (iomap->type == IOMAP_MAPPED) {
|
|
- if (iomap_dio_can_use_fua(iomap, dio))
|
|
- bio_opf |= REQ_FUA;
|
|
- else
|
|
- dio->flags &= ~IOMAP_DIO_WRITE_THROUGH;
|
|
- }
|
|
+ else if (iomap->type == IOMAP_MAPPED &&
|
|
+ iomap_dio_can_use_fua(iomap, dio))
|
|
+ bio_opf |= REQ_FUA;
|
|
+
|
|
+ if (!(bio_opf & REQ_FUA))
|
|
+ dio->flags &= ~IOMAP_DIO_WRITE_THROUGH;
|
|
|
|
/*
|
|
* We can only do deferred completion for pure overwrites that
|