forked from mirrors/linux
		
	io_uring: allow allocated fixed files for openat/openat2
If the application passes in IORING_FILE_INDEX_ALLOC as the file_slot, then that's a hint to allocate a fixed file descriptor rather than have one be passed in directly. This can be useful for having io_uring manage the direct descriptor space. Normal open direct requests will complete with 0 for success, and < 0 in case of error. If io_uring is asked to allocated the direct descriptor, then the direct descriptor is returned in case of success. Reviewed-by: Hao Xu <howeyxu@tencent.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
		
							parent
							
								
									b70b8e3331
								
							
						
					
					
						commit
						1339f24b33
					
				
					 2 changed files with 42 additions and 3 deletions
				
			
		|  | @ -4697,7 +4697,7 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) | |||
| 	return __io_openat_prep(req, sqe); | ||||
| } | ||||
| 
 | ||||
| static int __maybe_unused io_file_bitmap_get(struct io_ring_ctx *ctx) | ||||
| static int io_file_bitmap_get(struct io_ring_ctx *ctx) | ||||
| { | ||||
| 	struct io_file_table *table = &ctx->file_table; | ||||
| 	unsigned long nr = ctx->nr_user_files; | ||||
|  | @ -4722,6 +4722,36 @@ static int __maybe_unused io_file_bitmap_get(struct io_ring_ctx *ctx) | |||
| 	return -ENFILE; | ||||
| } | ||||
| 
 | ||||
| static int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, | ||||
| 			       struct file *file, unsigned int file_slot) | ||||
| { | ||||
| 	bool alloc_slot = file_slot == IORING_FILE_INDEX_ALLOC; | ||||
| 	struct io_ring_ctx *ctx = req->ctx; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (alloc_slot) { | ||||
| 		io_ring_submit_lock(ctx, issue_flags); | ||||
| 		ret = io_file_bitmap_get(ctx); | ||||
| 		if (unlikely(ret < 0)) { | ||||
| 			io_ring_submit_unlock(ctx, issue_flags); | ||||
| 			return ret; | ||||
| 		} | ||||
| 
 | ||||
| 		file_slot = ret; | ||||
| 	} else { | ||||
| 		file_slot--; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = io_install_fixed_file(req, file, issue_flags, file_slot); | ||||
| 	if (alloc_slot) { | ||||
| 		io_ring_submit_unlock(ctx, issue_flags); | ||||
| 		if (!ret) | ||||
| 			return file_slot; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int io_openat2(struct io_kiocb *req, unsigned int issue_flags) | ||||
| { | ||||
| 	struct open_flags op; | ||||
|  | @ -4777,8 +4807,8 @@ static int io_openat2(struct io_kiocb *req, unsigned int issue_flags) | |||
| 	if (!fixed) | ||||
| 		fd_install(ret, file); | ||||
| 	else | ||||
| 		ret = io_install_fixed_file(req, file, issue_flags, | ||||
| 					    req->open.file_slot - 1); | ||||
| 		ret = io_fixed_fd_install(req, issue_flags, file, | ||||
| 						req->open.file_slot); | ||||
| err: | ||||
| 	putname(req->open.filename); | ||||
| 	req->flags &= ~REQ_F_NEED_CLEANUP; | ||||
|  |  | |||
|  | @ -63,6 +63,15 @@ struct io_uring_sqe { | |||
| 	__u64	__pad2[2]; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * If sqe->file_index is set to this for opcodes that instantiate a new | ||||
|  * direct descriptor (like openat/openat2/accept), then io_uring will allocate | ||||
|  * an available direct descriptor instead of having the application pass one | ||||
|  * in. The picked direct descriptor will be returned in cqe->res, or -ENFILE | ||||
|  * if the space is full. | ||||
|  */ | ||||
| #define IORING_FILE_INDEX_ALLOC		(~0U) | ||||
| 
 | ||||
| enum { | ||||
| 	IOSQE_FIXED_FILE_BIT, | ||||
| 	IOSQE_IO_DRAIN_BIT, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jens Axboe
						Jens Axboe