@@ -502,6 +502,7 @@ struct io_poll_update {
502
502
struct io_close {
503
503
struct file * file ;
504
504
int fd ;
505
+ u32 file_slot ;
505
506
};
506
507
507
508
struct io_timeout_data {
@@ -1098,6 +1099,8 @@ static int io_req_prep_async(struct io_kiocb *req);
1098
1099
1099
1100
static int io_install_fixed_file (struct io_kiocb * req , struct file * file ,
1100
1101
unsigned int issue_flags , u32 slot_index );
1102
+ static int io_close_fixed (struct io_kiocb * req , unsigned int issue_flags );
1103
+
1101
1104
static enum hrtimer_restart io_link_timeout_fn (struct hrtimer * timer );
1102
1105
1103
1106
static struct kmem_cache * req_cachep ;
@@ -4591,12 +4594,16 @@ static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
4591
4594
if (unlikely (req -> ctx -> flags & IORING_SETUP_IOPOLL ))
4592
4595
return - EINVAL ;
4593
4596
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 )
4595
4598
return - EINVAL ;
4596
4599
if (req -> flags & REQ_F_FIXED_FILE )
4597
4600
return - EBADF ;
4598
4601
4599
4602
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
+
4600
4607
return 0 ;
4601
4608
}
4602
4609
@@ -4608,6 +4615,11 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
4608
4615
struct file * file = NULL ;
4609
4616
int ret = - EBADF ;
4610
4617
4618
+ if (req -> close .file_slot ) {
4619
+ ret = io_close_fixed (req , issue_flags );
4620
+ goto err ;
4621
+ }
4622
+
4611
4623
spin_lock (& files -> file_lock );
4612
4624
fdt = files_fdtable (files );
4613
4625
if (close -> fd >= fdt -> max_fds ) {
@@ -8401,6 +8413,44 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
8401
8413
return ret ;
8402
8414
}
8403
8415
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
+
8404
8454
static int __io_sqe_files_update (struct io_ring_ctx * ctx ,
8405
8455
struct io_uring_rsrc_update2 * up ,
8406
8456
unsigned nr_args )
0 commit comments