@@ -502,6 +502,7 @@ struct io_poll_update {
502502struct io_close {
503503 struct file * file ;
504504 int fd ;
505+ u32 file_slot ;
505506};
506507
507508struct io_timeout_data {
@@ -1098,6 +1099,8 @@ static int io_req_prep_async(struct io_kiocb *req);
10981099
10991100static int io_install_fixed_file (struct io_kiocb * req , struct file * file ,
11001101 unsigned int issue_flags , u32 slot_index );
1102+ static int io_close_fixed (struct io_kiocb * req , unsigned int issue_flags );
1103+
11011104static enum hrtimer_restart io_link_timeout_fn (struct hrtimer * timer );
11021105
11031106static struct kmem_cache * req_cachep ;
@@ -4591,12 +4594,16 @@ static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
45914594 if (unlikely (req -> ctx -> flags & IORING_SETUP_IOPOLL ))
45924595 return - EINVAL ;
45934596 if (sqe -> ioprio || sqe -> off || sqe -> addr || sqe -> len ||
4594- sqe -> rw_flags || sqe -> buf_index || sqe -> splice_fd_in )
4597+ sqe -> rw_flags || sqe -> buf_index )
45954598 return - EINVAL ;
45964599 if (req -> flags & REQ_F_FIXED_FILE )
45974600 return - EBADF ;
45984601
45994602 req -> close .fd = READ_ONCE (sqe -> fd );
4603+ req -> close .file_slot = READ_ONCE (sqe -> file_index );
4604+ if (req -> close .file_slot && req -> close .fd )
4605+ return - EINVAL ;
4606+
46004607 return 0 ;
46014608}
46024609
@@ -4608,6 +4615,11 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
46084615 struct file * file = NULL ;
46094616 int ret = - EBADF ;
46104617
4618+ if (req -> close .file_slot ) {
4619+ ret = io_close_fixed (req , issue_flags );
4620+ goto err ;
4621+ }
4622+
46114623 spin_lock (& files -> file_lock );
46124624 fdt = files_fdtable (files );
46134625 if (close -> fd >= fdt -> max_fds ) {
@@ -8401,6 +8413,44 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
84018413 return ret ;
84028414}
84038415
8416+ static int io_close_fixed (struct io_kiocb * req , unsigned int issue_flags )
8417+ {
8418+ unsigned int offset = req -> close .file_slot - 1 ;
8419+ struct io_ring_ctx * ctx = req -> ctx ;
8420+ struct io_fixed_file * file_slot ;
8421+ struct file * file ;
8422+ int ret , i ;
8423+
8424+ io_ring_submit_lock (ctx , !(issue_flags & IO_URING_F_NONBLOCK ));
8425+ ret = - ENXIO ;
8426+ if (unlikely (!ctx -> file_data ))
8427+ goto out ;
8428+ ret = - EINVAL ;
8429+ if (offset >= ctx -> nr_user_files )
8430+ goto out ;
8431+ ret = io_rsrc_node_switch_start (ctx );
8432+ if (ret )
8433+ goto out ;
8434+
8435+ i = array_index_nospec (offset , ctx -> nr_user_files );
8436+ file_slot = io_fixed_file_slot (& ctx -> file_table , i );
8437+ ret = - EBADF ;
8438+ if (!file_slot -> file_ptr )
8439+ goto out ;
8440+
8441+ file = (struct file * )(file_slot -> file_ptr & FFS_MASK );
8442+ ret = io_queue_rsrc_removal (ctx -> file_data , offset , ctx -> rsrc_node , file );
8443+ if (ret )
8444+ goto out ;
8445+
8446+ file_slot -> file_ptr = 0 ;
8447+ io_rsrc_node_switch (ctx , ctx -> file_data );
8448+ ret = 0 ;
8449+ out :
8450+ io_ring_submit_unlock (ctx , !(issue_flags & IO_URING_F_NONBLOCK ));
8451+ return ret ;
8452+ }
8453+
84048454static int __io_sqe_files_update (struct io_ring_ctx * ctx ,
84058455 struct io_uring_rsrc_update2 * up ,
84068456 unsigned nr_args )
0 commit comments