mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	io_uring/rsrc: ensure segments counts are correct on kbuf buffers
kbuf imports have the front offset adjusted and segments removed, but the tail segments are still included in the segment count that gets passed in the iov_iter. As the segments aren't necessarily all the same size, move importing to a separate helper and iterate the mapped length to get an exact count. Reviewed-by: Nitesh Shetty <nj.shetty@samsung.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
		
							parent
							
								
									80c7378f94
								
							
						
					
					
						commit
						b419bed4f0
					
				
					 1 changed files with 22 additions and 5 deletions
				
			
		|  | @ -1032,6 +1032,26 @@ static int validate_fixed_range(u64 buf_addr, size_t len, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int io_import_kbuf(int ddir, struct iov_iter *iter, | ||||||
|  | 			  struct io_mapped_ubuf *imu, size_t len, size_t offset) | ||||||
|  | { | ||||||
|  | 	size_t count = len + offset; | ||||||
|  | 
 | ||||||
|  | 	iov_iter_bvec(iter, ddir, imu->bvec, imu->nr_bvecs, count); | ||||||
|  | 	iov_iter_advance(iter, offset); | ||||||
|  | 
 | ||||||
|  | 	if (count < imu->len) { | ||||||
|  | 		const struct bio_vec *bvec = iter->bvec; | ||||||
|  | 
 | ||||||
|  | 		while (len > bvec->bv_len) { | ||||||
|  | 			len -= bvec->bv_len; | ||||||
|  | 			bvec++; | ||||||
|  | 		} | ||||||
|  | 		iter->nr_segs = 1 + bvec - iter->bvec; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int io_import_fixed(int ddir, struct iov_iter *iter, | static int io_import_fixed(int ddir, struct iov_iter *iter, | ||||||
| 			   struct io_mapped_ubuf *imu, | 			   struct io_mapped_ubuf *imu, | ||||||
| 			   u64 buf_addr, size_t len) | 			   u64 buf_addr, size_t len) | ||||||
|  | @ -1052,11 +1072,8 @@ static int io_import_fixed(int ddir, struct iov_iter *iter, | ||||||
| 
 | 
 | ||||||
| 	offset = buf_addr - imu->ubuf; | 	offset = buf_addr - imu->ubuf; | ||||||
| 
 | 
 | ||||||
| 	if (imu->is_kbuf) { | 	if (imu->is_kbuf) | ||||||
| 		iov_iter_bvec(iter, ddir, imu->bvec, imu->nr_bvecs, offset + len); | 		return io_import_kbuf(ddir, iter, imu, len, offset); | ||||||
| 		iov_iter_advance(iter, offset); |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Don't use iov_iter_advance() here, as it's really slow for | 	 * Don't use iov_iter_advance() here, as it's really slow for | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jens Axboe
						Jens Axboe