mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	gfs2: Prevent endless loops in gfs2_file_buffered_write
Currently, instead of performing a short write, iomap_file_buffered_write will fail when part of its iov iterator cannot be read. In contrast, gfs2_file_buffered_write will loop around if it can read part of the iov iterator, so we can end up in an endless loop. This should be fixed in iomap_file_buffered_write (and also generic_perform_write), but this comes a bit late in the 5.16 development cycle, so work around it in the filesystem by trimming the iov iterator to the known-good size for now. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
		
							parent
							
								
									a7ac203d8f
								
							
						
					
					
						commit
						554c577cee
					
				
					 1 changed files with 3 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1013,6 +1013,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
 | 
			
		|||
	struct gfs2_sbd *sdp = GFS2_SB(inode);
 | 
			
		||||
	struct gfs2_holder *statfs_gh = NULL;
 | 
			
		||||
	size_t prev_count = 0, window_size = 0;
 | 
			
		||||
	size_t orig_count = iov_iter_count(from);
 | 
			
		||||
	size_t read = 0;
 | 
			
		||||
	ssize_t ret;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1057,6 +1058,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
 | 
			
		|||
	if (inode == sdp->sd_rindex)
 | 
			
		||||
		gfs2_glock_dq_uninit(statfs_gh);
 | 
			
		||||
 | 
			
		||||
	from->count = orig_count - read;
 | 
			
		||||
	if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
 | 
			
		||||
		size_t leftover;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1064,6 +1066,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
 | 
			
		|||
		leftover = fault_in_iov_iter_readable(from, window_size);
 | 
			
		||||
		gfs2_holder_disallow_demote(gh);
 | 
			
		||||
		if (leftover != window_size) {
 | 
			
		||||
			from->count = min(from->count, window_size - leftover);
 | 
			
		||||
			if (!gfs2_holder_queued(gh)) {
 | 
			
		||||
				if (read)
 | 
			
		||||
					goto out_uninit;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue