mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	iomap: Fix broken data integrity guarantees for O_SYNC writes
Commitd279c80e0b("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:d279c80e0b("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>
This commit is contained in:
		
							parent
							
								
									d02d2c98d2
								
							
						
					
					
						commit
						6b65028e2b
					
				
					 1 changed files with 7 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -363,14 +363,14 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
 | 
			
		|||
		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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue