Skip to content

Commit 86de3aa

Browse files
jankaragregkh
authored andcommitted
iomap: Fix broken data integrity guarantees for O_SYNC writes
commit 6b65028 upstream. Commit d279c80 ("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: d279c80 ("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1334450 commit 86de3aa

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

fs/iomap/direct-io.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -368,14 +368,14 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
368368
if (iomap->flags & IOMAP_F_SHARED)
369369
dio->flags |= IOMAP_DIO_COW;
370370

371-
if (iomap->flags & IOMAP_F_NEW) {
371+
if (iomap->flags & IOMAP_F_NEW)
372372
need_zeroout = true;
373-
} else if (iomap->type == IOMAP_MAPPED) {
374-
if (iomap_dio_can_use_fua(iomap, dio))
375-
bio_opf |= REQ_FUA;
376-
else
377-
dio->flags &= ~IOMAP_DIO_WRITE_THROUGH;
378-
}
373+
else if (iomap->type == IOMAP_MAPPED &&
374+
iomap_dio_can_use_fua(iomap, dio))
375+
bio_opf |= REQ_FUA;
376+
377+
if (!(bio_opf & REQ_FUA))
378+
dio->flags &= ~IOMAP_DIO_WRITE_THROUGH;
379379

380380
/*
381381
* We can only do deferred completion for pure overwrites that

0 commit comments

Comments
 (0)